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

升级OData 8.2.3后自定义Query参数接口失效问题排查

问题分析与解决方案

问题根源

你关闭了OData的属性路由(EnableAttributeRouting = false),同时自定义接口使用了MVC的[Route]特性。在OData 8.x版本中,禁用属性路由时会启用传统约定式路由,此时你的自定义接口路径api/v1/department/getDepartmentsByCompany会被OData路由解析器错误识别为:尝试获取Department实体的key值为getDepartmentsByCompany(而该实体的key是int类型),因此抛出类型不匹配的错误。


解决方案

1. 启用OData属性路由

修改Program.cs中的OData配置,将EnableAttributeRouting设为true(OData 8.x推荐使用属性路由,可正确识别MVC的[Route]特性):

builder.Services.AddControllers(g =>
{
    g.EnableEndpointRouting = false;
}).AddOData(opt =>
    {
        var batchHandler = new DefaultODataBatchHandler();
        opt.AddRouteComponents("api/v1", DIRegister.GetEdmModels(), batchHandler);
        opt.Count().Select().Filter().OrderBy().Expand().SetMaxTop(int.MaxValue);
        opt.EnableQueryFeatures(int.MaxValue);
        // 启用属性路由,让自定义Route特性生效
        opt.EnableAttributeRouting = true;
    }).AddJsonOptions(g =>
    {
        g.AllowInputFormatterExceptionMessages = true;
    });

2. 排除OData路由处理(可选)

如果需要让自定义接口完全脱离OData路由的拦截,可以给接口添加[NonODataRoute]特性(OData 8.0+提供):

[HttpGet, Route("api/v1/department/getDepartmentsByCompany")]
[Microsoft.AspNetCore.OData.Query.EnableQuery]
[NonODataRoute] // 标记该接口不被OData路由处理
public Task<BaseResponse<IEnumerable<Department>>> GetDepartmentByCompany([FromQuery] int id, [FromQuery] FunctionalType? functionalType)
{
    try
    {
        return Task.FromResult(new BaseResponse<IEnumerable<Department>> { Data = /* 业务数据 */ });
    }
    catch (Exception ex)
    {
        LogHelper.LogException(ex, _hostingEnvironment);
        return Task.FromResult(new BaseResponse<IEnumerable<Department>> { Success = false, Message = "Failed" });
    }
}

3. 注册为OData函数(可选)

如果希望自定义接口支持OData查询能力并作为OData函数暴露,需在Edm模型中注册对应函数:

// 在DIRegister.GetEdmModels()中添加函数配置
var builder = new ODataConventionModelBuilder();
builder.EntitySet<Department>("Department");

// 注册集合函数
var getDepartmentsFunc = builder.EntityType<Department>().Collection
    .Function("getDepartmentsByCompany")
    .ReturnsCollection<Department>();
getDepartmentsFunc.Parameter<int>("id");
getDepartmentsFunc.Parameter<FunctionalType?>("functionalType");

return builder.GetEdmModel();

同时修改控制器接口的路由特性为OData专用:

[HttpGet]
[ODataRoute("getDepartmentsByCompany")]
[EnableQuery]
public Task<IEnumerable<Department>> GetDepartmentByCompany([FromODataUri] int id, [FromODataUri] FunctionalType? functionalType)
{
    // 业务逻辑实现
}

内容的提问来源于stack exchange,提问作者Gopi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 10:37:52