同名控制器的asp.net Web API路由 [英] asp.net web api route for controllers with same name

查看:44
本文介绍了同名控制器的asp.net Web API路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am integrating my project with another one

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

是否有一种方法可以使这种方式以最少的修改量起作用?

Is there a way to make this somehow work with the least amount of edit from either side?

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

I would like to avoid having to make modifications to all of my controllers.

谢谢

推荐答案

不幸的是,这不是很简单,因为默认控制器选择器(

Unfortunately, that is not very simple because default controller selector (DefaultHttpControllerSelector) does not look for namespace in the full controller name when it selects controller to process request.

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

So, there are at least two possible solutions to your problem:

  • Write your own IHttpControllerSelector which takes controller type namespace into account. Sample can be found here.
  • Rename one of controller types to make then unique.

TL; DR 默认控制器选择器使用控制器类型( HttpControllerTypeCache )的缓存,该缓存类似于:

TL;DR Default controller selector uses the cache of controller types (HttpControllerTypeCache) which holds something like:

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

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

So it uses controller name as dictionary key, but it can contain several types which have same controller name part. When request is received, controller selector gets controller name from route data. E.g. if you have default route specified "api/{controller}/{id}" then request api/customers/5 will map controller value to "customers". Controller selector then gets controller types which are registered for this name:

  • 如果有1种类型,那么我们可以实例化它并处理请求
  • 如果有0种类型,则会引发 NotFound 异常
  • 如果有2种或更多类型,则会引发 AmbiguousControllerException 异常(您的情况)
  • if there is 1 type, then we can instantiate it and process request
  • if there is 0 types, it throws NotFound exception
  • if there is 2 or more types, it throws AmbiguousControllerException exception (your case)

因此..另一个命名路由的定义将无济于事,因为您只能在此处提供控制器名称.您不能指定名称空间.

So.. definition of another named route will not help you, because you can only provide controller name there. You cannot specify namespace.

即使您将使用

Even if you'll use Attribute Routing and specify another route for one of the controller actions

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

您仍然会遇到控制器选择器问题,因为属性路由已应用于操作-路由数据中对于这些请求没有 controller 值.属性路由的处理方式有所不同-将它们作为"MS_attributerouteWebApi" 路由的子路由进行处理.

you will still face the controller selector problem because attribute routes are applied to actions - there will be no controller value in route data for those requests. Attributed routes are treated differently - they are processed as sub-routes of the "MS_attributerouteWebApi" route.

这篇关于同名控制器的asp.net Web API路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆