58

My Map is:

routes.MapRoute(
   "Default",                                             // Route name
   "{controller}/{action}/{id}",                          // URL with params
   new { controller = "Home", action = "Index", id = "" } // Param defaults
);

If I use the URL http://localhost:5000/Home/About/100%2f200 there is no matching route. I change the URL to http://localhost:5000/Home/About/100 then the route is matched again.

Is there any easy way to work with parameters that contain slashes? Other escaped values (space %20) seem to work.

EDIT:

To encode Base64 works for me. It makes the URL ugly, but that's OK for now.

public class UrlEncoder
{ 
    public string URLDecode(string  decode)
    {
        if (decode == null) return null;
        if (decode.StartsWith("="))
        {
            return FromBase64(decode.TrimStart('='));
        }
        else
        {
            return HttpUtility.UrlDecode( decode) ;
        }
    }

    public string UrlEncode(string encode)
    {
        if (encode == null) return null;
        string encoded = HttpUtility.PathEncode(encode);
        if (encoded.Replace("%20", "") == encode.Replace(" ", ""))
        {
            return encoded;
        }
        else
        {
            return "=" + ToBase64(encode);
        }
    }

    public string ToBase64(string encode)
    {
        Byte[] btByteArray = null;
        UTF8Encoding encoding = new UTF8Encoding();
        btByteArray = encoding.GetBytes(encode);
        string sResult = System.Convert.ToBase64String(btByteArray, 0, btByteArray.Length);
        sResult = sResult.Replace("+", "-").Replace("/", "_");
        return sResult;
    }

    public string FromBase64(string decode)
    {
        decode = decode.Replace("-", "+").Replace("_", "/");
        UTF8Encoding encoding = new UTF8Encoding();
        return encoding.GetString(Convert.FromBase64String(decode));
    }
}

EDIT1:

At the end it turned out that the best way was to save a nicely formated string for each item I need to select. Thats much better because now I only encode values and never decode them. All special characters become "-". A lot of my db-tables now have this additional column "URL". The data is pretty stable, thats why I can go this way. I can even check, if the data in "URL" is unique.

EDIT2:

Also watch out for space character. It looks ok on VS integrated webserver but is different on iis7 Properly url encode space character

4

10 回答 10

48

If it's only your last parameter, you could do:

routes.MapRoute(
    "Default",                                                // Route name
    "{controller}/{action}/{*id}",                            // URL with parameters
    new { controller = "Home", action = "Index", id = "" });  // Parameter defaults
于 2009-02-26T18:01:54.710 回答
26

这是对解决方案的简单解释和对已经说过的内容的总结。

请求方:

  1. UrlEncode 您的路径。
  2. 将 '%' 替换为 '!'。
  3. 提出请求。

回应方:

  1. 更换 '!' 和 '%'。
  2. UrlDecode 您的路径。
  3. 按预期使用参数。

冲洗,重复,享受。

于 2011-03-09T16:06:03.327 回答
24

在 .NET 4.0 beta 2 中,CLR 团队提供了一种解决方法。

将此添加到您的 web.config 文件中:

<uri> 
    <schemeSettings>
        <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
    </schemeSettings>
</uri>

这会导致 Uri 类根据描述 URI 的 RFC 运行,允许在路径中转义斜杠而不进行转义。CLR 团队报告说,出于安全原因,他们偏离了规范,并且在您的 .config 文件中进行设置基本上可以让您对不转义斜杠所涉及的其他安全考虑拥有所有权。

于 2009-11-16T23:00:58.267 回答
13

另一种选择是使用查询字符串值。很蹩脚,但比自定义编码更简单。

http://localhost:5000/Home/About?100%2f200
于 2009-11-14T18:15:45.783 回答
9

Java / Tomcat 也是如此。

如果您的 URL 中有编码的“/” (%2F),仍然存在问题。

RFC 3986 - 第 2.2 节说:“如果 URI 组件的数据与保留字符作为分隔符的目的发生冲突,则冲突数据必须在 URI 形成之前进行百分比编码。” (RFC 3986 - 第 2.2 节)

但是Tomcat有一个问题:

http://tomcat.apache.org/security-6.html - 在 Apache Tomcat 6.0.10 中修复

重要:目录遍历 CVE-2007-0450

Tomcat 允许 '\'、'%2F' 和 '%5C' [...]。

以下 Java 系统属性已添加到 Tomcat,以提供对 URL 中路径分隔符处理的额外控制(这两个选项默认为 false):

  • org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH:真|假
  • org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH:真|假

由于无法保证所有 URL 都由 Tomcat 处理,就像它们在代理服务器中一样,因此 Tomcat 应该始终受到保护,就好像没有使用限制上下文访问的代理一样。

影响:6.0.0-6.0.9

因此,如果您有一个带有 %2F 字符的 URL,Tomcat 会返回:“400 Invalid URI: noSlash”

您可以在 Tomcat 启动脚本中切换错误修复:

set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%   -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true 
于 2010-09-28T07:38:38.953 回答
1

您可以避免上述双重编码/解码建议,只需使用 HttpServerUtility.UrlTokenEncode 和相应的 UrlTokenDecode。

于 2016-03-16T17:15:13.283 回答
0

这对 .NET 4 很有趣。无论如何,此链接描述了 RFC 1738 并包括哪些字符需要编码,哪些只是“不安全”。 链接文本

如果我想要一个 SEO 友好的 URL(比如当您想在 URL 中放置论坛帖子主题时),则跳过编码并替换任何不是 AZ、az、0-9 的内容。

public static string CreateSubjectSEO(string str)
    {
        int ci;
        char[] arr = str.ToCharArray();
        for (int i = 0; i < arr.Length; i++)
        {
            ci = Convert.ToInt32(arr[i]);
            if (!((ci > 47 && ci < 58) || (ci > 64 && ci < 91) || (ci > 96 && ci < 123)))
            {
                arr[i] = '-';
            }
        }
        return new string(arr);
    }
于 2009-11-21T19:44:53.643 回答
0

对于入站编码的“/”问题,我可以通过添加“*”来捕获所有 id 参数来解决我的问题,然后能够正确地将编码的“/”传递到控件中(参数是一个带有编码的字符串'/')

routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{*id}",
            defaults: new 
            { 
                controller = "Control", 
                action = "Action", 
                id = UrlParameter.Optional 
            })
于 2019-04-24T16:28:00.597 回答
-1

正如Symfony 1.x 开发人员遇到问题时所建议的那样(+ 在PHP注释中urlencode()建议):

  • 之前将“/”编码为“%2F”urlencode()
  • 在(如有必要)之后将“%2F”解码为“/”urldecode()

注意:您可以使用rawurlencode(),但您仍然需要对 '/' 进行两次 urlencode。

优点:

  • 避免需要额外的转义过程(如果将 '/' 替换为特殊字符,如 '!' 或 '_')
  • 不要依赖任何服务器设置,例如AllowEncodedSlashesApache
于 2011-08-30T10:05:00.623 回答
-3

只需使用Server.UrlDecode. 它会起作用,我已经测试过了。

于 2012-06-22T07:23:13.350 回答