URL 中带有斜杠“/”的路由参数

Route parameter with slash "/" in URL

我知道您可以在路由属性中应用通配符以允许 / 例如日期输入:

[Route("orders/{*orderdate}")]

通配符的问题只适用于URI中的最后一个参数。如果想拥有以下 URI,如何解决问题:

[Route("orders/{orderdate}/customers")]

更新:

我知道通过重构代码来解决问题的选项很少,因此请不要提供类似以下的解决方案:

  1. 将路线模板更改为[Route("orders/customers/{orderdate}")]
  2. 将日期更改为不同的格式(例如 "dd-mm-yyyy"

如@AlexeiLevenkov 的评论所述,这是错误的:

You cannot have a parameter in the URL which accepts forward slashes, because this is a special symbol which separates each URL fragment. So, whenever you include this symbol in your URL, there will be new fragments, and a single parameter can't include several fragments.

如果您需要更多详细信息,read this,但这些是最相关的摘录:

  • URL 路径在 URL 中找到的第一个 ?# 结束。因此,斜杠只会在 URL 路径的部分中出现或这些符号之一之前创建片段。
  • 来自第 3.4 节:查询组件由第一个问号(“?”)字符指示,并以井号(“#”)字符或 URI 结尾结束。

因此,如果需要,查询字符串可以包含正斜杠 /,它们根本不会定义路径段。

这些是问题的一些解决方案:

  • 包括日月年的片段,如下所示:[Route("orders/{month}/{day}/{year}/customers")]然后在服务器端创建日期
  • 要求用户使用不同的分隔符,如破折号或点,这不会产生问题,在字符串中接收它并自行解析(或使用您自己的自定义活页夹来支持该格式)
  • 使用URL Rewrite extension在URL到达路由系统之前更改它,并按照前面的解决方案对其进行解析(这需要在 IIS 中托管)
  • 将其作为查询字符串接收,即类似这样的内容:´?date=02/03/2015´(您最好对其进行编码)

注意:您最初的问题是“查询字符串”,而我关于编码的评论是指查询字符串,它是问号后 URL 的最后一段,如果目前,like &id=27。我更正了你的问题,所以它没有提到“查询字符串”,这不是你需要的正确名称

@bet.. 我认为 genericUriParserOptions 不再适用于 .net 4.5 或更高版本..

同样如 @JotaBe 所建议,您可能需要正确解码 url 请求。在大多数情况下,%2F 会自动转换为斜杠 '/'。所以如果你需要转义它,你需要首先解码 '%' 字符。所以你的 URL: 看起来像:www.domain.com/api/orders/23%252F06%252F2015/customers

注意字符 '%252F' 将被翻译成实际的 '%2F'

编辑

好的,这是完整的解决方案(试过并为我工作):

  1. 假设您有一个 API 端点,如下所示:

    [Route("orders/{date}/customers")]
    public HttpResponseMessage Get(string date)
    {
    }
    
  2. web.config 中,您需要将 requestPathInvalidCharacters 设置为空,这告诉 asp.net 允许所有请求

    <system.web>
        <httpRuntime targetFramework="4.5" requestPathInvalidCharacters=""/>                
    </system.web>
    <system.webServer>
        <security>
          <requestFiltering allowDoubleEscaping="true" />
        </security>
    </system.webServer>
    
  3. 当客户端向 API 发送请求时,您需要确保像这样转义 '%'

    www.domain.com/api/orders/23%252F06%252F2015/客户

  4. 然后您需要解码请求

    [Route("orders/{date}/customers")]
    public HttpResponseMessage Get(string date)
    {
            DateTime actualDate = DateTime.Parse(System.Net.WebUtility.UrlDecode(date)); // date is 23/06/2015
    }
    

您可以使用以下 URI [Route("orders/{DD:int}/{MM:int}/{YY:int}}/customers")] 然后使用自定义模型活页夹获取 DD/MM/YY 并将它们转换为您可以在操作方法中绑定的日期。

您可以选择处理约束的方式(使用正则表达式更加严格)或使用验证,如果不匹配则 return 400。

更简单的方法是,将 Day/Month/Year 放在代码中。

这是 dealing with modelbinding 的 link。

C#有自己的方法可以跳过转义序列的规则 方法的名称是 Uri.UnescapeDataString(你的查询字符串参数) 您可以在获取参数值时使用它