I’m working on moving an API project from raw http handlers where I’m using periods in the paths:
http://server/collection/id.format
I would like to follow the same URL schema in a Web Api (self-hosted) version, and tried this:
var c = new HttpSelfHostConfiguration(b);
c.Routes.MapHttpRoute(
name: "DefaultApiRoute",
routeTemplate: "{controller}/{id}.{format}",
defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional },
constraints: null
);
Unfortunately, that doesn’t seem to resolve (consistent 404’s on /foo, /foo/bar and /foo/bar.txt). A similar pattern using a slash before ‘format’ works fine:
var c = new HttpSelfHostConfiguration(b);
c.Routes.MapHttpRoute(
name: "DefaultApiRoute",
routeTemplate: "{controller}/{id}/{format}",
defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional },
constraints: null
);
I haven’t yet delved into the code for the Web Api, and before I do thought I’d ask here to see if this is a known, or perhaps even justified limitation in Web Api.
UPDATE: I neglected to mention that “id” and “format” are strings, which turns out to be important for the solution to this question. Adding a constraint to exclude periods from the “id” token solves the 404 problem.
I am unable to reproduce the problem. This should work. Here’s my setup:
Microsoft.AspNet.WebApi.SelfHostNuGetDefine a
ProductA corresponding API Controller:
And a host:
Now when you run this console application you could navigate to
http://localhost:8080/products/123.xml. But of course you could navigate tohttp://localhost:8080/products/123.jsonand you will still get XML. So the question is: How to enable content negotiation using a route parameter?You could do the following:
and now you can use the following urls:
Now you might be wondering what’s the relation between the
{ext}route parameter that we used in our route definition and theAddUriPathExtensionMappingmethod because nowhere we did not specify it. Well, guess what: it’s hardcoded in theUriPathExtensionMappingclass toextand you cannot modify it because it is readonly:All this to answer your question:
Yes.