【问题标题】:asp.net web api route for controllers with same name具有相同名称的控制器的 asp.net web api 路由
【发布时间】:2017-06-16 14:54:45
【问题描述】:

我正在将我的项目与另一个项目集成

Multiple types were found that match the controller named 'XXXXX'. 
This can happen if the route that services this request ('api/{controller}/{action}/{id}') found multiple controllers defined with the same name but differing namespaces, which is not supported. 
The request for 'XXXXX' has found the following matching controllers: 
COM.example.host.XXXXXController 
COM.example.parasite.XXXXXController

有没有办法让这一切以最少的编辑量从任何一方工作?

我希望避免对我的所有控制器进行修改。

谢谢

【问题讨论】:

  • 要么合并到同一个类,要么改名,要么改路由。

标签: asp.net asp.net-web-api


【解决方案1】:

不幸的是,这不是很简单,因为默认控制器选择器 (DefaultHttpControllerSelector) 在选择控制器来处理请求时不会在完整的控制器名称中查找命名空间。

因此,您的问题至少有两种可能的解决方案:

  • 编写您自己的IHttpControllerSelector,它将控制器类型命名空间考虑在内。样品可以在here找到。
  • 重命名控制器类型之一,使其独一无二。

TL;DR 默认控制器选择器使用控制器类型的缓存 (HttpControllerTypeCache),其中包含以下内容:

{
   "Customers" : [
        typeof(Foo.CustomersController),
        typeof(Bar.CustomersController)        
   ],
   "Orders" : [
       typeof(Foo.OrdersController)
   ]
}

所以它使用控制器名称作为字典键,但它可以包含多个具有相同控制器名称部分的类型。当收到请求时,控制器选择器从路由数据中获取控制器名称。例如。如果您指定了默认路由"api/{controller}/{id}",则请求api/customers/5 会将控制器 值映射到"customers"。然后控制器选择器获取为此名称注册的控制器类型:

  • 如果有 1 种类型,那么我们可以实例化它并处理请求
  • 如果有0个类型,则抛出NotFound异常
  • 如果有 2 种或更多类型,则抛出 AmbiguousControllerException 异常(您的情况)

所以.. 另一个命名路由的定义对你没有帮助,因为你只能在那里提供控制器名称。不能指定命名空间。

即使您将使用 Attribute Routing 并为其中一个控制器操作指定另一条路线

[RoutePrefix("api/customers2")]
public class CustomersController : ApiController
{
     [Route("")]
     public IHttpActionResult Get()
     //...
}

您仍将面临控制器选择器问题,因为属性路由应用于操作 - 这些请求的路由数据中将没有 controller 值。属性路由的处理方式不同 - 它们作为"MS_attributerouteWebApi" 路由的子路由处理。

【讨论】:

  • 谢谢,我最终编写了一个自定义控制器选择器并使其表现得像它的 mvc 对应物。希望在未来的某个时候,他们会提供一种可以处理命名空间的标准。
  • 拯救了我的一天。对于其他有 404 错误的人:可能是您的项目中有重复的控制器类名称(在不同的命名空间中)。拥有唯一的控制器类名称是避免头痛的好习惯。
【解决方案2】:

对您来说最简单的方法可能是将基于操作的路由添加到您的 Web api:

RouteTable.Routes.MapRoute(
     "WithActionApi",
     "api/{controller}/{action}/{id}"
 );

对于您的 WebApiConfig.cs,请务必将其置于默认规则之上。然后,通过包含方法名称来更改调用控制器的方式,此时方法名称应该或应该是唯一的。

【讨论】:

    猜你喜欢
    • 2020-09-19
    • 1970-01-01
    • 2017-03-10
    • 2014-10-07
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    相关资源
    最近更新 更多