I am unable to reproduce the problem. This should work. Here's my setup:
- Create a new .NET 4.0 Console Application
- Switch to .NET Framework 4.0 profile
- Install the
Microsoft.AspNet.WebApi.SelfHost
NuGet
Define a Product
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
A corresponding API Controller:
public class ProductsController : ApiController
{
public Product Get(int id)
{
return new Product
{
Id = id,
Name = "prd " + id
};
}
}
And a host:
class Program
{
static void Main(string[] args)
{
var config = new HttpSelfHostConfiguration("http://localhost:8080");
config.Routes.MapHttpRoute(
name: "DefaultApiRoute",
routeTemplate: "{controller}/{id}.{format}",
defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional },
constraints: null
);
using (var server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
Console.WriteLine("Press Enter to quit.");
Console.ReadLine();
}
}
}
Now when you run this console application you could navigate to http://localhost:8080/products/123.xml
. But of course you could navigate to http://localhost:8080/products/123.json
and you will still get XML. So the question is: How to enable content negotiation using a route parameter?
You could do the following:
class Program
{
static void Main(string[] args)
{
var config = new HttpSelfHostConfiguration("http://localhost:8080");
config.Formatters.XmlFormatter.AddUriPathExtensionMapping("xml", "text/html");
config.Formatters.JsonFormatter.AddUriPathExtensionMapping("json", "application/json");
config.Routes.MapHttpRoute(
name: "DefaultApiRoute",
routeTemplate: "{controller}/{id}.{ext}",
defaults: new { id = RouteParameter.Optional, formatter = RouteParameter.Optional },
constraints: null
);
using (var server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
Console.WriteLine("Press Enter to quit.");
Console.ReadLine();
}
}
}
and now you can use the following urls:
http://localhost:8080/products/123.xml
http://localhost:8080/products/123.json
Now you might be wondering what's the relation between the {ext}
route parameter that we used in our route definition and the AddUriPathExtensionMapping
method because nowhere we did not specify it. Well, guess what: it's hardcoded in the UriPathExtensionMapping
class to ext
and you cannot modify it because it is readonly:
public class UriPathExtensionMapping
{
public static readonly string UriPathExtensionKey;
static UriPathExtensionMapping()
{
UriPathExtensionKey = "ext";
}
...
}
All this to answer your question:
Can periods be used in Asp.Net Web Api Routes?
Yes.