Catch-all route fails to find route with WebApi2 ApiController

asp.net, asp.net-web-api2, attributerouting, c#

Solution

Web api routing is not the same as routing MVC. instead of

route.MapRoute

try

public static void Register(HttpConfiguration config) {
    config.MapHttpAttributeRoutes

    config.Routes.MapHttpRoute(
        name: "CatchAll", routeTemplate: "values/path/{*pathvalue}", 
        defaults: new {id = RouteParameter.Optional });
}

The reason it works from controller is that MapRoute is the correct format for routing an MVC controller, while MapHttpRoute is designed for API controllers.

Problem

I am creating a WebApi2 service, and one of the methods I want to implement represents an HTTP GET from an object within an internal tree structure - so the request would be along the lines of: ``` GET /values/path/path/to/object/in/tree ``` So I would want my method to receive "path/to/object/in/tree". However, I just get a 404 when I run this, and it's interesting that I get a 404 that is different looking to the standard IIS 404. It's titled 'Server Error in '/' Application.', whereas the one for a completely invalid resource is titled 'HTTP Error 404.0 - Not Found'. I am playing around with the default template to try and see if I can get this to work, hence the similarity. I have this for my `RouteConfig` ``` public static void RegisterRoutes(RouteCollection routes) { var route = routes.MapRoute( name: "CatchAllRoute", url: "values/path/{*pathValue}", defaults: new { controller = "Values", action = "GetPath" }); } ``` And this is my `ValuesController`: ``` [System.Web.Mvc.AuthorizeAttribute] [RoutePrefix("values")] public class ValuesController : ApiController { [Route("test/{value}")] [HttpGet] public string Test(string value) { return value; } [HttpGet] public string GetPath(string pathValue) { return pathValue; } } ``` Interestingly, if I derive from `Controller` rather than `ApiController` it works OK, but then the normal attribute routing doesn't work. I tried following the methodology in this post (http://www.tugberkugurlu.com/archive/asp-net-web-api-catch-all-route-parameter-binding) but I couldn't get it to work. I'm sure I'm missing something stupidly easy, but having spent a few hours on it I thought it prudent to ask what I'm doing wrong. Thanks M

Original source