URL 中带有斜杠“/”的路由参数
Route parameter with slash "/" in URL
我知道您可以在路由属性中应用通配符以允许 /
例如日期输入:
[Route("orders/{*orderdate}")]
通配符的问题只适用于URI中的最后一个参数。如果想拥有以下 URI,如何解决问题:
[Route("orders/{orderdate}/customers")]
更新:
我知道通过重构代码来解决问题的选项很少,因此请不要提供类似以下的解决方案:
- 将路线模板更改为
[Route("orders/customers/{orderdate}")]
- 将日期更改为不同的格式(例如
"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'
编辑
好的,这是完整的解决方案(试过并为我工作):
假设您有一个 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/客户
然后您需要解码请求
[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(你的查询字符串参数)
您可以在获取参数值时使用它
我知道您可以在路由属性中应用通配符以允许 /
例如日期输入:
[Route("orders/{*orderdate}")]
通配符的问题只适用于URI中的最后一个参数。如果想拥有以下 URI,如何解决问题:
[Route("orders/{orderdate}/customers")]
更新:
我知道通过重构代码来解决问题的选项很少,因此请不要提供类似以下的解决方案:
- 将路线模板更改为
[Route("orders/customers/{orderdate}")]
- 将日期更改为不同的格式(例如
"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'
编辑
好的,这是完整的解决方案(试过并为我工作):
假设您有一个 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/客户
然后您需要解码请求
[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(你的查询字符串参数) 您可以在获取参数值时使用它