7

In my web app, my parameters can contain all sorts of crazy characters (russian chars, slashes, spaces etc) and can therefor not always be represented as-is in a URL.
Sending them on their merry way will work in about 50% of the cases. Some things like spaces are already encoded somewhere (I'm guessing in the Html.BuildUrlFromExpression does). Other things though (like "/" and "*") are not.

Now I don't know what to do anymore because if I encode them myself, my encoding will get partially encoded again and end up wrong. If I don't encode them, some characters will not get through.

What I did is manually .replace() the characters I had problems with.
This is off course not a good idea.

Ideas?

--Edit--
I know there are a multitude of encoding/decoding libraries at my disposal. It just looks like the mvc framework is already trying to do it for me, but not completely.

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

will render me

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

Notice how the forward slash, asterisk and ampersand are not escaped. Why are some escaped and others not? How can I now escape this properly?

Am I doing something wrong or is it the framework?

4

8 回答 8

2

Parameters should be escaped using 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]));
                }
            }
于 2008-10-27T15:16:49.023 回答
1

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

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

于 2008-12-23T09:16:17.200 回答
0

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

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

于 2008-12-24T18:48:43.487 回答
0

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

于 2008-11-03T10:11:51.220 回答
0

Have you tried using the Server.UrlEncode() method to do the encoding, and the Server.UrlDecode() method to decode?

I have not had any issues with using it for passing items.

于 2008-10-27T15:13:07.110 回答
0

Server.URLEncode or HttpServerUtility.UrlEncode

I see what you're saying now - I didn't realize the question was specific to MVC. Looks like a limitation of that part of the MVC framework - particularly BuildUrlFromExpression is doing some URL encoding, but it knows that also needs some of those punctation as part of the framework URLs.

And also unfortunately, URLEncoding doesn't produce an invariant, i.e.

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

Wouldn't that be nice. Then you could pre-encode your variables and they wouldn't be double encoded.

There's probably an ASP.NET MVC framework best practice for this. I guess another thing you could do is encode into base64 or something that is URLEncode-invariant.

于 2008-10-27T15:13:35.143 回答
0

Try using the Microsoft Anti-Cross Site Scripting library. It contains several Encode methods, which encode all the characters (including #, and characters in other languages). As for decoding, the browser should handle the encoded Url just fine, however if you need to manually decode the Url, use Uri.UnescapeDataString

Hope that helps.

于 2008-10-27T15:19:07.723 回答
0

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

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

于 2008-12-19T06:41:14.073 回答