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.
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));
...
}
}