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

Posted

技术标签:

【中文标题】URL 中带有斜杠“/”的路由参数【英文标题】:Route parameter with slash "/" in URL 【发布时间】:2015-09-07 11:15:56 【问题描述】:

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

[Route("orders/*orderdate")]

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

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

更新:

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

    将路由模板更改为[Route("orders/customers/orderdate")] 将日期更改为其他格式(例如"dd-mm-yyyy"

【问题讨论】:

我很感激。我不知道您可以在路线中使用通配符,也就是*orderdate 中的*。这实际上解决了我的问题,因为我的参数位于 URL 的末尾。 【参考方案1】:

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

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

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

编辑

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

    假设您有这样的 API 端点:

    [Route("orders/date/customers")]
    public HttpResponseMessage Get(string date)
    
    
    

    web.config 中,您需要将 requestPathInvalidCharacters 设置为空,这告诉 asp.net 允许所有请求

    <system.web>
        <httpRuntime targetFramework="4.5" requestPathInvalidCharacters=""/>                
    </system.web>
    <system.webServer>
        <security>
          <requestFiltering allowDoubleEscaping="true" />
        </security>
    </system.webServer>
    

    当客户端向 API 发送请求时,您需要确保转义 '%',如下所示:

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

    然后你需要解码请求

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

【讨论】:

我不明白这如何回答用户的问题。 @Daniel.. 如果您知道更好的方法,请在此处发布!我过去处理过同样的问题并使用'%252F'解决了它 @ronnie - 似乎在为我做这项工作 完美!!我的 web.config 中缺少“ requestPathInvalidCharacters="" " 不需要双重转义。【参考方案2】:

正如@AlexeiLevenkov 在评论中指出的那样,这是错误的:

您不能在 URL 中包含接受正斜杠的参数,因为这是分隔每个 URL 片段的特殊符号。所以,每当你在你的 URL 中包含这个符号时,都会有新的片段,并且单个参数不能包含多个片段。

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

URL 路径在 URL 中找到的第一个 ?# 处结束。因此,斜杠只会在 URL 路径部分中出现之前或其中一个符号之前创建片段。 从第 3.4 节开始:查询组件由第一个问号 ("?") 字符指示,并以数字符号 ("#") 字符或 URI 结尾结束。

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

以下是该问题的一些解决方案:

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

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

【讨论】:

用 '%2F' 尝试过,但没有运气...给了我无效的请求错误 这与正确编码无关!当 API 收到请求时,'%2F' 将自动被视为 '/' 还尝试在机器和网络配置中设置以下设置,但没有成功.. &lt;uri&gt; &lt;schemeSettings&gt; &lt;add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" /&gt; &lt;add name="https" genericUriParserOptions="DontUnescapePathDotsAndSlashes" /&gt; &lt;/schemeSettings&gt; &lt;/uri&gt; 可以在路径中使用/(按百分比编码%2f)和查询参数(按原样或编码)-tools.ietf.org/html/rfc3986#section-3.3。所以大部分答案都是错误的,但建议的解决方案可以作为解决方法(前半部分 -1,后半部分 +1 =0) @AlexeiLevenkov 好点。我已经更正了我的答案以反映那个大错误【参考方案3】:

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

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

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

这是dealing with modelbinding 的链接。

【讨论】:

【参考方案4】:

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

【讨论】:

以上是关于URL 中带有斜杠“/”的路由参数的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 中带有 URL 参数的路由

Laravel 5中带有可选参数的url中的两个斜杠

ASP.NET Web API 中带有可选参数的属性路由

WCF Rest 4.0 中没有斜杠的简单 URL 路由

在url中带参数

ASP.NET MVC 2 中带有约束的可选路由参数?