简体   繁体   English

在URL中使用斜杠“/”路由参数

[英]Route parameter with slash “/” in URL

I know you can apply a wildcard in the route attribute to allow / such as date input for example: 我知道你可以在路由属性中应用通配符来允许/例如日期输入,例如:

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

The problem with wildcard is only applicable to the last paramter in URI. 通配符的问题仅适用于URI中的最后一个参数。 How do I solve the issue if want to have the following URI: 如果要拥有以下URI,如何解决问题:

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

Update: 更新:

I know there are few options to solve the issue by refactoring the code so please do not offer a solution something like: 我知道通过重构代码来解决问题的选择很少,所以请不要提供类似的解决方案:

  1. change the route template to [Route("orders/customers/{orderdate}")] 将路线模板更改为[Route("orders/customers/{orderdate}")]
  2. change the date to a different format (eg "dd-mm-yyyy" ) 将日期更改为其他格式(例如"dd-mm-yyyy"

@bet.. I think the genericUriParserOptions is no longer applicable to .net 4.5 or later.. @bet ..我认为genericUriParserOptions不再适用于.net 4.5或更高版本..

Also as suggested by @JotaBe , you might need to correctly decode the url request. 另外,正如@JotaBe所建议的那样 ,您可能需要正确解码网址请求。 In most case the %2F will be automatically translated to a slash '/' . 在大多数情况下, %2F将自动转换为斜杠'/' So if you need to escape it you will need to decode the '%' char in the first place.. so your URL: will look something like: www.domain.com/api/orders/23%252F06%252F2015/customers 因此,如果你需要逃避它,你需要首先解码'%'字符..所以你的URL:看起来像: www.domain.com/api/orders/23%252F06%252F2015/customers

Notice the characters '%252F' will be translated to the actual '%2F' 请注意,字符'%252F'将转换为实际'%2F'

EDIT 编辑

Ok here is the complete solution (Tried it and working for me): 好的,这是完整的解决方案(试过它并为我工作):

  1. Assuming you have an API endpoint like so: 假设你有一个像这样的API端点:

     [Route("orders/{date}/customers")] public HttpResponseMessage Get(string date) { } 
  2. In the web.config you will need to set the requestPathInvalidCharacters to empty which tells the asp.net to allow all request web.config中,您需要将requestPathInvalidCharacters设置为empty,告诉asp.net允许所有请求

     <system.web> <httpRuntime targetFramework="4.5" requestPathInvalidCharacters=""/> </system.web> <system.webServer> <security> <requestFiltering allowDoubleEscaping="true" /> </security> </system.webServer> 
  3. When the client sending the request to the API you will need to make sure to escape the '%' like so: 当客户端向API发送请求时,您需要确保像这样转义'%'

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

  4. You then need to decode the request 然后,您需要解码请求

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

As noted in the comment by @AlexeiLevenkov, this is wrong: 如@AlexeiLevenkov的评论所述,这是错误的:

You cannot have a parameter in the URL which accepts forward slashes, because this is a special symbol which separates each URL fragment. 您不能在URL中有一个接受正斜杠的参数,因为这是一个分隔每个URL片段的特殊符号。 So, whenever you include this symbol in your URL, there will be new fragments, and a single parameter can't include several fragments. 因此,只要在URL中包含此符号,就会有新的片段,并且单个参数不能包含多个片段。

If you want more details, read this , but these are the most relevant excerpts: 如果您想了解更多详情,请阅读本文 ,但这些是最相关的摘录:

  • the URL path finishes in the first ? URL路径在第一个完成? or # found in the URL. #在网址中找到。 So, the slashes only create fragments in the section of the URL path before the occurrence or one of those symbols. 因此,斜杠仅在出现之前的URL路径部分或其中一个符号中创建片段。
  • From section 3.4: The query component is indicated by the first question mark ("?") character and terminated by a number sign ("#") character or by the end of the URI. 从3.4节开始:查询组件由第一个问号(“?”)字符表示,并以数字符号(“#”)字符或URI的末尾结束。

So, the query string can include forward slashes, / , if desired, and they will not define path segments at all. 因此,查询字符串可以包含正斜杠, / ,如果需要的话,他们不会在所有定义路径段。

These are some solutions for the question: 这些是问题的一些解决方案:

  • include fragments for day, month and year, like this: [Route("orders/{month}/{day}/{year}/customers")] and then create the date on the server side 包括日,月和年的片段,如下所示: [Route("orders/{month}/{day}/{year}/customers")]然后在服务器端创建日期
  • require the user to use a different separator, like dash or dot, which won't create problems, receive it at string an parse it yourself (or use your own custom binder to support that format) 要求用户使用不同的分隔符,如破折号或点,这不会产生问题,在字符串处接收它并自行解析(或使用您自己的自定义绑定器来支持该格式)
  • use the URL Rewrite extension to change the URL before it reaches the routing system, and parse it as explained in the previous solution (this requires hosting in IIS) 使用URL Rewrite扩展名在URL到达路由系统之前更改URL,并按照上一个解决方案中的说明解析它(这需要在IIS中托管)
  • receive it as a query string, ie something like this: ´?date=02/03/2015´ (you'd better encode it) 接收它作为查询字符串,即这样的东西:'?date = 02/03 / 2015'(你最好编码)

NOTE: your original question said "query string", and my comment about encoding referred to the query string, which is the last segment of an URL after the question mark, if present, like &id=27 . 注意:您的原始问题是“查询字符串”,而我对编码的评论是指查询字符串,它是问号后面的URL的最后一段(如果存在), like &id=27 I corrected your question so that it doesn't mention "query string", which was not the right name for what you need 我更正了你的问题,所以它没有提到“查询字符串”,这不是你需要的正确名称

You can use the following URI [Route("orders/{DD:int}/{MM:int}/{YY:int}}/customers")] and then use a custom model binder to take DD/MM/YY and turn them into a date that you can bind in your action method. 您可以使用以下URI [Route("orders/{DD:int}/{MM:int}/{YY:int}}/customers")]然后使用自定义模型绑定器来获取DD/MM/YY和将它们转换为您可以在动作方法中绑定的日期。

You can choose how you want to deal with constraints (go stricter with regex's) or use validation and return 400 if it doesn't match. 您可以选择如何处理约束(更严格地使用正则表达式)或使用验证并返回400(如果不匹配)。

The simpler approach is, to take the Day/Month/Year and put it together in code. 更简单的方法是采用Day/Month/Year并将其放在代码中。

Here is a link for dealing with modelbinding . 这是一个处理模型绑定的链接。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM