You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何手动从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 09:12:04