6

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

1
  • Either merge them into the same class, or change their names, or change the routing. Commented Jun 16, 2017 at 14:55

2 Answers 2

8

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, I ended up writing a custom controller selector and make it behave like its mvc counterpart. Hopefully, sometime in the future they will provide a standard one that can handle namespaces.
Saved my day. For others with 404 errors: It can be that you have duplicate controller class name in your project (in different namespaces). Having unique ontroller class names is a good practice to avoid the headache.
-1

The easiest path for you might be to add action based routing to your web api:

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

To your WebApiConfig.cs, be sure to put it above the default rule. Then, change how you call your controllers by including the method name, which at this point should be or should be made unique.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.