如何手动从HttpContext读取ODataQueryOptions解决NSwag生成代码弊端
解决方案实现
你需要先安装对应.NET版本的Microsoft.AspNetCore.OData NuGet包,即可直接调用OData官方提供的参数解析API完成扩展方法实现,无需手动解析查询参数:
using Microsoft.AspNetCore.OData; using Microsoft.AspNetCore.OData.Extensions; using Microsoft.AspNetCore.OData.Query; using Microsoft.OData.Edm; using Microsoft.AspNetCore.Http; public static class ODataQueryOptionsExtensions { public static ODataQueryOptions<T> ReadODataQueryOptions<T>(this HttpRequest request) { // 从请求服务中读取预配置的EDM模型 IEdmModel edmModel = request.GetModel(); // 匹配EDM中注册的对应实体类型 IEdmEntityType entityType = edmModel.EntityContainer.EntitySets() .First(s => s.EntityType().Name == typeof(T).Name) .EntityType(); // 构造OData查询上下文 var queryContext = new ODataQueryContext(edmModel, entityType, request.ODataFeature().Path); // 官方原生方法直接解析当前请求的所有OData参数 return new ODataQueryOptions<T>(queryContext, request); } }
前置配置要求
你需要在OData服务注册时提前绑定对应Dto的EDM模型,示例配置如下:
builder.Services.AddControllers().AddOData(opt => { var edmBuilder = new ODataConventionModelBuilder(); // 注册所有需要用到OData查询的Dto,实体集名称建议和控制器名称保持一致 edmBuilder.EntitySet<BrandDto>("Brands"); // 开启需要用到的OData能力 opt.Select().Filter().OrderBy().Expand().Count().SetMaxTop(100); opt.AddRouteComponents("api/v1", edmBuilder.GetEdmModel()); });
控制器使用示例
不需要在方法参数中声明ODataQueryOptions,完全不会影响NSwag的客户端代码生成:
[Authorize(Policy = Permissions.Brands.View)] [HttpGet] [Produces(typeof(IReadOnlyCollection<BrandDto>))] public async Task<IActionResult> GetAll([FromOdataFilter] TransferableExpression<BrandDto> filter = null, CancellationToken cancellationToken = default) { // 直接从当前请求中解析完整的OData参数 var odataOptions = Request.ReadODataQueryOptions<BrandDto>(); // 将参数传入Mediator查询,即可在数据库层统一处理所有OData逻辑 var brands = await Mediator.Send(new GetAllBrandsQuery(filter, odataOptions), cancellationToken); return Ok(brands); }
注意事项
- 去掉全局
[EnableQuery]特性,避免自动在内存中执行OData操作,所有逻辑由你自己在业务层/数据层控制,不会出现两套逻辑混用的问题 - 如果EDM实体集名称和Dto类名不一致,调整扩展方法中查找实体集的逻辑,和你注册时的名称对应即可
- ASP.NET Core 3.1及以下版本需要将命名空间替换为
Microsoft.AspNet.OData,API逻辑保持一致
内容的提问来源于stack exchange,提问作者Florian Gilde
相关产品推荐
相关产品推荐

