Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp.net web api route for controllers with same name

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.

Thank you

like image 956
herme 0 Avatar asked Jun 16 '17 14:06

herme 0


Video Answer


1 Answers

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 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)
   ]
}

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:

  • 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()
     //...
}

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.

like image 159
Sergey Berezovskiy Avatar answered Oct 18 '22 10:10

Sergey Berezovskiy