【问题标题】:Why is ASP.NET MVC returning multiple types matching a controller?为什么 ASP.NET MVC 返回与控制器匹配的多种类型?
【发布时间】:2021-06-06 21:34:57
【问题描述】:

我正在尝试使用 ASP.NET MVC4 设置版本化 API。 Global.asax.csSystem.Web.Http.GlobalConfiguration.Configuration 在我的项目WebApiConfig.Register 中调用一个方法。 WebApiConfig.Register 的代码如下所示:

public static void Register(HttpConfiguration config)
{
    CreateRoute(
        routes: config.Routes,
        name: "Root",
        routeTemplate: "api",
        defaults: new { },
        constraints: new { },
        namespaces: new[] { "MyApp.Controllers.Api" },
    );

    CreateRoute(
        routes: config.Routes,
        name: "API",
        routeTemplate: "api/{controller}/{action}",
        defaults: new { action = "Get" },
        constraints: new { },
        namespaces: new[] { "MyApp.Controllers.Api" },
    );

    CreateRoute(
        routes: config.Routes,
        name: "API v2",
        routeTemplate: "api/v2/{controller}/{action}",
        defaults: new { action = "Get" },
        constraints: new { },
        namespaces: new[] { "MyApp.Controllers.Api.v2" },
    );
}

private static void CreateRoute(HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, string[] namespaces)
{
    var defaultsDictionary = new HttpRouteValueDictionary(defaults);
    var constraintsDictionary = new HttpRouteValueDictionary(constraints);
    var dataTokensDictionary = new HttpRouteValueDictionary(new { Namespaces = namespaces, UseNamespaceFallback = false });
    var route = routes.CreateRoute(routeTemplate, defaultsDictionary, constraintsDictionary, dataTokensDictionary);
    routes.Add(name, route);
}

我有两个名为UsersController 的控制器,一个在MyApp.Controllers.Api.UsersController,一个在MyApp.Controllers.Api.v2.UsersController。当我提出POST /api/users/Login 之类的请求时,我得到了500 Multiple types were found that match the controller names 'users'. This can happen if the route that services this request ('api/{controller}/{action}') found multiple controllers defined with the same name but differing namespaces, which is not supported.\r\n\r\nThe request for 'users' has found the following matching controllers:\r\nMyApp.Controllers.Api.v2.UsersController\r\nMyApp.Controllers.Api.UsersController 的响应

如您所见,我专门在路由上设置命名空间,并将UseNamespaceFallback 设置为false 以避免冲突,但无论如何它们都会发生。我该如何解决这个问题?

【问题讨论】:

  • 您的答案似乎可以在这里找到:stackoverflow.com/questions/7842293/…
  • 不。该问题的答案是在声明路由时使用命名空间。我已经在这样做了。请仔细阅读我的问题。
  • 尝试将通用的第一个路由配置移到所有特定路由的最后一个。
  • 感谢您的建议。我试过了,但我仍然遇到同样的错误。然后我尝试注释掉路由,看看是哪一个导致了问题,我可以确认它是名称为API的路由。

标签: c# asp.net asp.net-mvc asp.net-mvc-4 routes


【解决方案1】:

MyApp.Controllers.Api.v2.UsersController 在命名空间MyApp.Controllers.Api 中。所以在同一个命名空间中有两个UsersController

使用UseNamespaceFallback仅仅意味着如果v2命名空间中没有UsersController,检查之前的命名空间所以设置它的值对非v2命名空间没有影响,命名空间有问题。

您应该能够将第一个命名空间更新为:

MyApp.Controllers.Api.v1.UsersController
// and then
MyApp.Controllers.Api.v2.UsersController

然后你可以更新命名空间参数:

namespaces: new[] { "MyApp.Controllers.Api.v1" },

【讨论】:

  • 我尝试将命名空间 MyApp.Controllers.Api.v2 重命名为 MyApp.Controllers.Foobar(所以它不会以其他命名空间开头),我得到了同样的错误。
  • 并更改了路由中的命名空间值?
【解决方案2】:

我不知道为什么没有提到更多的地方,但显然 System.Web.Http.Dispatcher.DefaultHttpControllerSelector(顾名思义,默认解析控制器)不支持 Namespaces 数据令牌(或任何其他方式限制命名空间)。我可以通过添加对 WebApiContrib 的 Nuget 引用并将我的 API 配置为在 Global.asax.cs 中使用 NamespaceHttpControllerSelector 来修复我的路由:

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration));

【讨论】:

猜你喜欢
  • 2023-04-06
  • 1970-01-01
  • 2014-05-19
  • 2016-07-27
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多