可以在Asp.Net Web Api路由中使用句点吗?

我正在努力从原始的http处理程序移动API项目,我在路径中使用句点:

http://server/collection/id.format 

我想在Web Api(自托管)版本中遵循相同的URL架构,并尝试这样做:

 var c = new HttpSelfHostConfiguration(b); c.Routes.MapHttpRoute( name: "DefaultApiRoute", routeTemplate: "{controller}/{id}.{format}", defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional }, constraints: null ); 

不幸的是,这似乎没有解决(在/ foo,/ foo / bar和/foo/bar.txt上一致的404’)。 在’format’之前使用斜杠的类似模式工作正常:

 var c = new HttpSelfHostConfiguration(b); c.Routes.MapHttpRoute( name: "DefaultApiRoute", routeTemplate: "{controller}/{id}/{format}", defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional }, constraints: null ); 

我还没有深入研究Web Api的代码,在此之前我想过我会在这里询问这是否是Web Api中已知的,甚至是合理的限制。

更新:我忽略了提到“id”和“format”是字符串,这对于解决这个问题很重要。 添加约束以从“id”标记中排除句点可解决404问题。

我无法重现这个问题。 这应该工作。 这是我的设置:

  1. 创建一个新的.NET 4.0控制台应用程序
  2. 切换到.NET Framework 4.0配置文件
  3. 安装Microsoft.AspNet.WebApi.SelfHost NuGet
  4. 定义Product

     public class Product { public int Id { get; set; } public string Name { get; set; } } 
  5. 相应的API控制器:

     public class ProductsController : ApiController { public Product Get(int id) { return new Product { Id = id, Name = "prd " + id }; } } 
  6. 和主持人:

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

现在,当您运行此控制台应用程序时,您可以导航到http://localhost:8080/products/123.xml 。 但是当然你可以导航到http://localhost:8080/products/123.json ,你仍然可以获得XML。 所以问题是:如何使用路由参数启用内容协商?

您可以执行以下操作:

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

现在您可以使用以下url:

 http://localhost:8080/products/123.xml http://localhost:8080/products/123.json 

现在您可能想知道我们在路由定义中使用的{ext}路由参数与AddUriPathExtensionMapping方法之间的关系是什么,因为我们没有指定它。 好吧,猜猜看:它在UriPathExtensionMapping类中硬编码为ext ,你无法修改它,因为它是只读的:

 public class UriPathExtensionMapping { public static readonly string UriPathExtensionKey; static UriPathExtensionMapping() { UriPathExtensionKey = "ext"; } ... } 

这一切都是为了回答你的问题:

可以在Asp.Net Web Api路由中使用句点吗?

是。

通过执行以下操作,我能够实现此目的:替换"*." 在web.config中的system.webServer.handlers中使用"*" ,即删除句点。

  

请注意在web.config中的modules属性中设置runAllManagedModulesForAllRequests选项

 .. 

否则它将无法在IIS中工作(可能由非托管处理程序处理)。

我接受了达林的答案(是的,句号可用于路线url)因为它对我的例子特别正确,但对我没有帮助。 这是我的错,因为没有明确指出“id”是一个字符串,而不是一个整数。

要使用字符串参数后面的句点,路由引擎需要以约束forms提示:

 var c = new HttpSelfHostConfiguration(b); c.Routes.MapHttpRoute( name: "DefaultApiRoute", routeTemplate: "{controller}/{id}.{format}", defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional }, constraints: new { id = "[^\\.]+" } // anything but a period ); 

将约束添加到前一个令牌可以正确分解和处理入站URL。 如果没有提示,则可以解释“id”标记以匹配URL的剩余范围。 这只是需要约束来描述字符串参数之间的边界的特定情况。

是的,可以在Asp.Net Web API中的URL路由中使用句点,但如果它们要遵循字符串参数,请确保对路径应用正确的约束。

IIS以文件下载的句点拦截请求。 在您的web.config中,您可以将IIS配置为忽略特定的URL路径,因为webapi将处理请求。 如果希望IIS处理文件下载以及处理webapi调用,可以将webagedDllExtension配置添加到web.config中的system.webServer.handlers。