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?

Boris Callens
  • 90,659
  • 85
  • 207
  • 305

8 Answers8

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]));
                }
            }
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
1

AS others have mentioned, if you encode your string first you aviod the issue.

The MVC Framework is encoding characters that it knows it needs to encode, but leaving those that are valid URL characters (e.g. & % ? * /). This is because these are valid URL characters, although they are special chracters in a URL that might not acheive the result you are after.

Ady
  • 4,736
  • 2
  • 22
  • 20
  • 1
    Wouldn't characters with system-used characters make even more reason to encode them? I don't see any reason why I should pass in a parameter that does already do (part of) the work the actual method is supposed to do. – Boris Callens Aug 03 '09 at 09:51
  • It's not because they are system used, but because they are not valid characters according to the URL specification that they are encoded. However other characters that define meaning in a URL are not encoded because the are perfectly valid. – Ady Sep 09 '09 at 10:55
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.

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
Mitchel Sellers
  • 62,228
  • 14
  • 110
  • 173
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.

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
Cade Roux
  • 88,164
  • 40
  • 182
  • 265
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.

Community
  • 1
  • 1
Igal Tabachnik
  • 31,174
  • 15
  • 92
  • 157
  • It's a usefull link alright, but I think it's not gonna solve my problem. I tried to make my problem more clear in my edit. Please have a look. – Boris Callens Oct 27 '08 at 16:03
0

Escaping of forward slahes and dots in path part of url is prohibited by security reason (althrough, it works in mono).

derigel
  • 3,218
  • 2
  • 19
  • 31
  • why is that? what with parameters that require these things... I know I should try not to have these, but it's an external data source. People use it to search things. There is no way I can change the data... – Boris Callens Nov 05 '08 at 15:17
0

Html.BuildUrlFromExpression needs to be fixed then, would submit this upstream to the MVC project... alternatively do the encoding to the string before passing to BuildUrlFromExpression, and decode it when it comes back out on the other side.

It may not be readily fixable, as IIS may be handling the decoding of the url string beforehand... may need to do some more advanced encoding/decoding for alternative path characters in the utility methods, and decode on your behalf coming out.

Tracker1
  • 19,103
  • 12
  • 80
  • 106
0

I've seen similar posts on this. Too me, it looks like a flaw in MVC. The function would be more appropriately named "BuildUrlFromEncodedExpression". Whats worse, is that the called function needs to decode its input parameters. Yuk.

If there is any overlap between the characters encoded BuildUrlFromExpression() and the characters encoded by the caller (who, I think might fairly just encode any non-alphanumeric for simplicities sake) then you have potential for nasty bugs.

Frank Schwieterman
  • 24,142
  • 15
  • 92
  • 130