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

ASP.NET Core Web API MapControllerRoute配置models路由返回404问题排查

问题原因

你遇到的404问题核心是OData路由优先级高于普通MVC常规路由,触发了路由抢占,具体原因如下:

  • 你在EdmModel中注册了名为Models的实体集,而ModelsController继承自ODataController,OData路由系统会优先匹配和实体集同名的/models路径
  • OData匹配/models路径时,会查找符合OData约定的Get方法,你原本符合约定的Get()方法已经被注释,实际存在的GetModels()不符合OData默认的方法名匹配规则,OData匹配失败后直接返回404,不会继续向下匹配你后续注册的MapControllerRoute自定义路由
  • 而Projects对应的实体没有在EdmModel中注册,OData不会抢占/projects路径,请求可以正常匹配到后续的自定义路由,所以访问正常
解决方案

可以根据你的业务需求任选以下一种方案解决:

方案1:调整路由注册顺序(最便捷)

路由匹配遵循先注册先匹配的规则,你可以把所有自定义的MapControllerRoute注册逻辑移到endpoints.MapControllers();之前,让自定义路由优先匹配:

app.UseEndpoints(endpoints =>
{
    // 先注册自定义常规路由,优先匹配
    endpoints.MapControllerRoute(
        name: "test",
        pattern: "test/data",
        defaults: new { controller = "Models", action = "addsampledata" }
    );
    endpoints.MapControllerRoute(
        name: "projects",
        pattern: "projects/create",
        defaults: new { controller = "Projects", action = "createproject" }
    );
    endpoints.MapControllerRoute(
        name: "projects",
        pattern: "projects",
        defaults: new { controller = "Projects", action = "getprojects" }
    );
    endpoints.MapControllerRoute(
        name: "models",
        pattern: "models",
        defaults: new { controller = "Models", action = "getmodels" }
    );
    endpoints.MapControllerRoute(
        name: "models",
        pattern: "models/create",
        defaults: new { controller = "Models", action = "createmodel" }
    );
    endpoints.MapControllerRoute(
        name: "models",
        pattern: "models/retrieve/{model}",
        defaults: new { controller = "Models", action = "retrievemodels" }
    );

    // 最后注册控制器路由(包含OData路由)
    endpoints.MapControllers();
});

方案2:修改OData实体集名称,避免路由冲突

修改EdmModel中注册的实体集名称,不要和自定义路由的/models路径重名:

private static IEdmModel GetEdmModel()
{
    var builder = new ODataConventionModelBuilder();
    // 把实体集名称从Models改成其他值,比如ODataModels
    builder.EntitySet<Model>("ODataModels").EntityType.HasMany(m => m.SubModels);
    builder.EntitySet<Property>("Propterties");
    return builder.GetEdmModel();
}

方案3:适配OData路由规则

如果你希望/models路径走OData路由,直接取消ModelsController中注释的Get()方法即可,或者给GetModels()方法加上OData路由特性匹配规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:45:03