【问题标题】:Double/incomplete Parameter Url Encoding双重/不完整的参数 URL 编码
【发布时间】:2008-10-27 15:08:55
【问题描述】:

在我的网络应用程序中,我的参数可以包含各种疯狂的字符(俄语字符、斜杠、空格等),因此不能总是在 URL 中按原样表示。
在大约 50% 的情况下,让他们以愉快的方式送他们去。像空格这样的东西已经在某处编码(我猜是在 Html.BuildUrlFromExpression 中)。其他的东西(比如“/”和“*”)不是。

现在我不知道该怎么做了,因为如果我自己编码它们,我的编码将再次部分编码并最终出错。如果我不对其进行编码,某些字符将无法通过。

我所做的是手动 .replace() 我遇到问题的字符。
这当然不是一个好主意。

想法?

--编辑--
我知道有许多编码/解码库可供我使用。 看起来 mvc 框架已经在尝试为我做这件事,但并不完全。

<a href="<%=Html.BuildUrlFromExpression<SearchController>(c=>c.Search("", 1, "a \v/&irdStr*ng"))%>" title="my hat's awesome!">

会渲染我

<a href="/Search.mvc/en/Search/1/a%20%5Cv/&irdStr*ng" title="my hat's awesome!">

注意正斜杠、星号和 & 号是如何不被转义的。 为什么有的逃了,有的逃了?我现在怎样才能正确地逃脱呢?

我做错了什么还是框架?

【问题讨论】:

    标签: c# asp.net-mvc encoding


    【解决方案1】:

    参数应该使用Uri.EscapeDataString转义:

                string url = string.Format("http://www.foo.bar/page?name={0}&address={1}",
                    Uri.EscapeDataString("adlknad /?? lkm#"),
                    Uri.EscapeDataString(" qeio103 8182"));
    
                Console.WriteLine(url);
                Uri uri = new Uri(url);
                string[] options = uri.Query.Split('?','&');
                foreach (string option in options)
                {
                    string[] parts = option.Split('=');
                    if (parts.Length == 2)
                    {
                        Console.WriteLine("{0} = {1}",parts[0],
                            Uri.UnescapeDataString(parts[1]));
                    }
                }
    

    【讨论】:

    • 感谢您的反馈,但请注意 asp.net-mvc 标签。我编辑了我的问题以澄清问题。
    【解决方案2】:

    正如其他人所提到的,如果您首先对字符串进行编码,则可以避免该问题。

    MVC 框架正在对它知道需要编码的字符进行编码,但保留那些有效的 URL 字符(例如 & % ? * /)。这是因为这些是有效的 URL 字符,尽管它们是 URL 中的特殊字符,可能无法达到您想要的结果。

    【讨论】:

    • 具有系统使用字符的字符不是更有理由对其进行编码吗?我看不出有任何理由为什么我应该传入一个已经完成(部分)实际方法应该完成的工作的参数。
    • 不是因为它们是系统使用的,而是因为根据 URL 规范,它们不是有效字符,所以它们被编码。但是,在 URL 中定义含义的其他字符不会被编码,因为它们是完全有效的。
    【解决方案3】:

    尝试使用Microsoft Anti-Cross Site Scripting library。它包含几个 Encode 方法,对所有字符(包括 # 和其他语言的字符)进行编码。至于解码,浏览器应该可以很好地处理编码的Url,但是如果您需要手动解码Url,请使用Uri.UnescapeDataString

    希望对您有所帮助。

    【讨论】:

    • 这是一个有用的链接,但我认为它不会解决我的问题。我试图在我的编辑中使我的问题更清楚。请看一看。
    【解决方案4】:

    出于安全原因,禁止在 url 的路径部分中转义正斜杠和点(尽管它在单声道中工作)。

    【讨论】:

    • 这是为什么呢?需要这些东西的参数是什么......我知道我应该尽量不要有这些,但它是一个外部数据源。人们用它来搜索东西。我无法更改数据...
    【解决方案5】:

    Html.BuildUrlFromExpression 需要修复,然后将这个上游提交给 MVC 项目......或者在传递给 BuildUrlFromExpression 之前对字符串进行编码,并在它从另一端返回时对其进行解码。

    它可能不容易修复,因为 IIS 可能会事先处理 url 字符串的解码...可能需要在实用程序方法中对替代路径字符进行一些更高级的编码/解码,并代表您进行解码出去。

    【讨论】:

      【解决方案6】:

      我看过类似的帖子。对我来说,这看起来像是 MVC 中的一个缺陷。该函数将更恰当地命名为“BuildUrlFromEncodedExpression”。更糟糕的是,被调用的函数需要对其输入参数进行解码。呵呵。

      如果在 BuildUrlFromExpression() 编码的字符和调用者编码的字符之间有任何重叠(为了简单起见,我认为调用者可能只是对任何非字母数字进行编码),那么您就有可能出现严重的错误。

      【讨论】:

        【解决方案7】:

        Server.URLEncodeHttpServerUtility.UrlEncode

        我明白你现在在说什么 - 我没有意识到这个问题是特定于 MVC 的。看起来像是 MVC 框架的那一部分的限制 - 特别是 BuildUrlFromExpression 正在执行一些 URL 编码,但它知道也需要其中一些标点作为框架 URL 的一部分。

        不幸的是,URLEncoding 不会产生不变量,即

        URLEncode(x) != URLEncode(URLEncode(x))
        

        那不是很好。然后你可以对你的变量进行预编码,它们不会被双重编码。

        这可能有一个 ASP.NET MVC 框架最佳实践。我想您可以做的另一件事是编码为 base64 或 URLEncode-invariant。

        【讨论】:

        【解决方案8】:

        您是否尝试过使用Server.UrlEncode() 方法进行编码,并使用Server.UrlDecode() 方法进行解码?

        我在使用它传递物品方面没有任何问题。

        【讨论】:

        • 感谢您的反馈。请参阅我的原始帖子以了解我所做的编辑。我认为我的问题不够清楚。
        猜你喜欢
        • 1970-01-01
        • 2011-11-11
        • 2014-04-05
        • 1970-01-01
        • 2011-07-02
        • 2012-04-24
        • 1970-01-01
        • 2020-06-29
        相关资源
        最近更新 更多