可以在 Asp.Net Web Api 路由中使用句点吗? [英] Can periods be used in Asp.Net Web Api Routes?

查看:20
本文介绍了可以在 Asp.Net Web Api 路由中使用句点吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

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

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

我还没有深入研究 Web Api 的代码,在我考虑之前,我会在这里询问这是否是 Web Api 中已知的,或者甚至是合理的限制.

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.

更新:我忽略了id"和format"是字符串,这对于解决这个问题很重要.添加约束以从id"令牌中排除句点可以解决 404 问题.

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:

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

  • 相应的 API 控制器:

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

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

    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?

    您可以执行以下操作:

        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
    

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

    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:

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

    Can periods be used in Asp.Net Web Api Routes?

    是的.

    这篇关于可以在 Asp.Net Web Api 路由中使用句点吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆