Change the Entity Data Model Structure Exposed in OData(更改在 OData 中公开的实体数据模型结构 )
This article describes techniques that you can use to customize the Web API Service’s OData interface including the availability of particular endpoints and the structure of data written to the service’s responses.
本文介绍了可用于自定义Web API Service的OData接口的技术,包括特定端点的可用性以及写入服务响应的数据结构。
Change the Expansion Depth for Related Business Objects(更改相关业务对象的扩展深度)
To specify the ODataValidationSettings.MaxExpansionDepth option, follow the steps below:
要指定ODataValidationSettings. MaxExpansionDepth选项,请执行以下步骤:
- Implement a custom ODataQueryValidator service to set MaxExpansionDepth:(实现自定义ODataQueryValidator服务以设置MaxExpansionDepth:)
C#
using Microsoft.AspNetCore.OData.Query.Validator;
using Microsoft.AspNetCore.OData.Query;
// ...
public class MyODataQueryValidator : ODataQueryValidator {
public override void Validate(ODataQueryOptions options, ODataValidationSettings validationSettings){
validationSettings.MaxExpansionDepth = 3;
base.Validate(options, validationSettings);
}
}
- Replace the default ODataQueryValidator service with the custom service in the ConfigureServices method:(将默认的ODataQueryValidator服务替换为配置服务方法中的自定义服务:)
File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)
C#
public void ConfigureServices(IServiceCollection services) {
// ...
services.AddControllers().AddOData((options, serviceProvider) => {
options
.EnableQueryFeatures(100)
.AddRouteComponents("api/odata", new EdmModelBuilder(serviceProvider).GetEdmModel(), odataServices => {
odataServices.AddSingleton<ODataQueryValidator, MyODataQueryValidator>();
});
});
// ...
}
Enable/Disable Web Actions for Business Objects(为业务对象启用/禁用Web操作)
Use the techniques described below to enable or disable specific combinations of OData endpoints and HTTP verbs for business objects in your Web API Service application.
使用下面描述的技术为Web API服务应用程序中的业务对象启用或禁用OData端点和HTTP谓词的特定组合。
Important
We recommend that you configure Type, Object, and Member security permissions for your business objects. Ensure that your API controls data access or CRUD operations depending on the user role. In addition, you can use the techniques described in this section to prevent execution of specific web actions on a business object at the Swagger UI and OData query levels.
我们建议您为业务对象配置类型、对象和成员安全权限。确保您的API根据用户角色控制数据访问或CRUD操作。此外,您可以使用本节中描述的技术来防止在Swagger UI和OData查询级别对业务对象执行特定的Web操作。
- Use the WebApiOptions.ConfigureDataControllers extension method to enable/disable web actions globally for all business objects:(使用WebApiOptions.ConfigureDataControllers扩展方法为所有业务对象全局启用/禁用Web操作:)
File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)
C#
services.AddXafWebApi(builder => {
builder.ConfigureOptions(options => {
options.ConfigureDataControllers(b => {
// Place your logic to customize the availability of web actions here.
// You can use one of the following methods:
// - b.WithActions(a => !a.ActionName.Contains("Ref"));
// - b.WithActions(WebApiActions.PostEntity | WebApiActions.GetEntity);
// - b.ReadOnly();
});
});
}, Configuration);
- Use the BusinessObjectConfigurator.ConfigureController method to enable/disable web actions for a specific business object. If this method is called for a business object, it overrides all effects of WebApiOptions.ConfigureDataControllers for this object.(使用BusinessObjectConfigurator。配置控制器方法为特定业务对象启用/禁用Web操作。如果为业务对象调用此方法,它会覆盖WebApiOptions的所有效果。ConfigureDataControllers此对象。)
File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)
C#
services.AddXafWebApi(builder => {
builder.ConfigureOptions(options => {
options.BusinessObject<MyEntity>().ConfigureController(b => {
// Place your logic to customize the availability of web actions here.
// You can use one of the following methods:
// - b.WithActions(a => !a.ActionName.Contains("Ref"));
// - b.WithActions(WebApiActions.PostEntity | WebApiActions.GetEntity);
// - b.ReadOnly();
});
});
}, Configuration);
Both methods take a delegate as a parameter. The delegate’s argument exposes the WithActions method, which has two overloads that you can use in the following ways:
这两种方法都将委托作为参数。委托的参数公开了SupActions方法,该方法有两个重载,您可以通过以下方式使用:
- Allow web actions based on an arbitrary predicate:(允许基于任意谓词的Web操作:)
File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)
C#
options.BusinessObject<MyEntity>().ConfigureController(b => {
b.WithActions(a => !a.ActionName.Contains("Ref"));
});
- Use predefined bit flags:(使用预定义的位标志:)
File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)
C#
options.BusinessObject<MyEntity>().ConfigureController(b => {
b.WithActions(WebApiActions.PostEntity | WebApiActions.GetEntity);
});
The WebApiActions enumeration defines the following bit flags:
WebApiActions枚举定义了以下位标志:
You can also use the ReadOnly method to only allow read actions. This method has the same effect as the ReadOnly bit flag.
您还可以使用ReadOnly方法只允许读取操作。此方法与ReadOnly位标志具有相同的效果。
File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)
C#
options.BusinessObject<MyEntity>().ConfigureController(b => {
b.ReadOnly();
// The above line is equivalent to:
// b.WithActions(WebApiActions.ReadOnly);
});
The AllActions method allows you to enable all web actions for a specific business class when some of the actions are prohibited globally.
AllActions方法允许您在全局禁止某些操作时为特定业务类启用所有Web操作。
C#
options.BusinessObject<MyEntity>().ConfigureController(b => {
b.AllActions();
});
For example, the image below demonstrates how the Swagger UI reflects a business object configured in read-only mode.
例如,下图演示了Swagger UI如何反映以只读模式配置的业务对象。
Important
Keep in mind that the hidden endpoints are not only invisible in Swagger, but are entirely unavailable through the OData interface.
请记住,隐藏的端点不仅在Swagger中不可见,而且通过OData接口完全不可用。
Configure an OData Entity Type(配置OData实体类型)
Use one of the following techniques to customize the OData entity data model structure.
使用以下技术之一自定义OData实体数据模型结构。
Use the OnCustomizeEdmModel property(使用OnCustomizeEdmModel属性)
The WebApiEvents.OnCustomizeEdmModel property allows you to customize the OData entity data model structure at runtime (change types, properties, actions, and so on).
WebApiEvent. OnCustomizeEdmModel属性允许您在运行时自定义OData实体数据模型结构(更改类型、属性、操作等)。
For example, you can implement custom logic that adds a property that was removed from the model by the IgnoreDataMemberAttribute.
例如,您可以实现自定义逻辑,添加IgnoreDataMemberAttribute从模型中删除的属性。
File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)
C#
services.AddXaf(Configuration, builder => {
//...
builder.AddXafWebApi(webApiBuilder => {
webApiBuilder.ConfigureOptions(options => {
options.Events.OnCustomizeEdmModel = context => {
context.ODataModelBuilder.AddEntityType(typeof(MyEntity)).AddProperty(typeof(MyEntity).GetProperty(nameof(MyEntity.MyProperty)));
};
//...
});
});
});
public class MyEntity : BaseObject {
[IgnoreDataMember]
public virtual int MyProperty { get; set; }
//...
}
Use the ODataModelBuilder(使用ODataModelBuilder)
Implement the DevExpress.ExpressApp.WebApi.Services.IEdmModelCustomizer interface in a custom class. In your implementation of the class CustomizeEdmModel method, use the ODataModelBuilder to customize the OData entity data model based on your requirements.
在自定义类中实现DevExpress.ExpressApp.WebApi.Services. IEdmModelCustomizer接口。在CustomizeEdmModel类方法的实现中,使用ODataModelBuilder根据您的要求自定义OData实体数据模型。
You can register your IEdmModelCustomizer implementation after the services.AddXafWebApi call in the ConfigureServices method:
您可以在配置服务方法中的services. AddXafWebApi调用之后注册您的IEdmModelCustomizer实现:
File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)
C# (Standalone WEB API Service)
services.AddXafWebApi(options => { /* ... */ }, Configuration);
services.TryAddEnumerable(ServiceDescriptor.Transient<IEdmModelCustomizer, CustomEdmModelCustomizer>());
C# (XAF Application Builder)
services.AddXaf(Configuration, builder => {
//...
builder.AddXafWebApi(webApiBuilder => { /* ... */ });
});
services.TryAddEnumerable(ServiceDescriptor.Transient<IEdmModelCustomizer, CustomEdmModelCustomizer>());
For more information, refer to the following resources:
有关详细信息,请参阅以下资源:
- Model builders overview(模型构建器概述)
- Code of the built-in IEdmModelCustomizer implementers (DateTimeNullableEdmModelCustomizer, PersistentAliasEdmModelCustomizer, etc.) within the DevExpress.ExpressApp.WebApi library sources(DevExpress. ExpressApp.WebApi库源代码中的内置IEdmModelCustomizer实现程序(DateTimeNullableEdmModelCustomizer、PersistentAliasEdmModelCustomizer等)的代码)
- Support articles:(支持文章:)
- Web API - The “400 Bad Request” error occurs when you use properties with NotMappedAttribute in EF Core-based apps(Web API-当您在基于EF Core的应用程序中将属性与NotMapdAtoral一起使用时,会出现“400错误请求”错误)
- *Web API Service - How to return or serialize a business object in a custom method/endpoint of API controller?(*Web API服务-如何在API控制器的自定义方法/端点中返回或序列化业务对象?)
- Web API - How to create a custom ODataController for each business object type to create own custom endpoints(Web API-如何为每个业务对象类型创建自定义ODataController以创建自己的自定义端点)
Use the EntityTypeConfiguration(用EntityTypeConfiguration)
The EntityTypeConfigurator.ConfigureODataEntityType method allows you to directly access an EntityTypeConfiguration instance for your business class. Use the API exposed through the instance to configure the entity type.
EntityTypeConfiguratorConfigureODataEntityType方法允许您直接访问业务类的EntityTypeConfiguration实例。使用通过实例公开的API来配置实体类型。
For example, you can add a property that was hidden from the Entity Data Model by the IgnoreDataMemberAttribute as shown below.
例如,您可以添加一个被IgnoreDataMemberAttribute隐藏在实体数据模型中的属性,如下所示。
File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)
C#
services.AddXafWebApi(builder => {
builder.ConfigureOptions(options => {
options.BusinessObject<MyEntity>().ConfigureEntityType(b => {
// Add the current business class ignored property.
b.ConfigureODataEntityType(d => d.Property(o => o.IgnoredProperty));
// Add the base class ignored property.
b.ConfigureODataEntityType(
// You can access the `BaseType` properties sequentially to get to
// an arbitrary ancestor's configurator (`d.BaseType.BaseType ...`)
d => d.BaseType.AddProperty(
typeof(MyEntity)
.GetProperty(nameof(BusinessEntityBase.BaseClassIgnoredProperty))
)
);
});
});
}, Configuration);