2

I'd like to have a catch all route that matches a general route prefix ("api/myaccount/1") execute if there are no more specific routes defined on other controllers (i.e "api/myaccount/1/feature") however I get the following exception when I do this:

Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL.

As mentioned here: Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL it seems this may not be possible.

Wanting a default route to execute when no better one is found sounds pretty common so what am I missing? Do I need to hook lower in the pipeline or something...


FYI: I have the catch all working fine ("api/myaccount/1/{*uri}") it's just the being able to override it that's the problem.

Community
  • 1
  • 1
Justin_H
  • 407
  • 5
  • 19

1 Answers1

4

Turns out this is pretty easy, I just needed to create a custom Controller Selector and override the GetControllerName function. That particular override is required because the method you would expect to override:

HttpControllerDescriptor SelectController(HttpRequestMessage request) 

does not just return the descriptor (or null if It can't find a match) as you may expect. The method actually handles the request for you and returns a 404 :/ However once you're aware of that it is trivial to work around and I was able to get the behavior I wanted using the code below:

using System.Web.Http;
using System.Web.Http.Dispatcher;

public class CustomControllerSelector : DefaultHttpControllerSelector
{
    public override string GetControllerName(HttpRequestMessage request)
    {
        var name =  base.GetControllerName(request);
        if(string.IsNullOrEmpty(name))
        {
            return "MyFeature"; //important not to include "Controller" suffix
        }
        return name;
    }
}

And add it to your configuration:

 public static class WebApiConfig
 {
     public static void Register(HttpConfiguration config)
     {
          ...

          config.Services.Replace(typeof(IHttpControllerSelector),
              new CustomControllerSelector(config));
          ...
     }
 }
Justin_H
  • 407
  • 5
  • 19