views:

2715

answers:

8

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?

A: 

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.

Mitchel Sellers
Thanks for your feedback. Please see my original post for the edit I made. I think my question wasn't clear enough.
borisCallens
A: 

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.

Cade Roux
UrlEncode strangely enough doesn't use this http://www.w3schools.com/TAGS/ref_urlencode.asp. Space for example gets encoded to %25.
borisCallens
HttpUtility.UrlPathEncode does though
borisCallens
Indeed that is my problem. Thanks for passing by again.
borisCallens
+2  A: 

Parameters should be escaped using Uri.EscapeDataString:

            string url = string.Format("http://www.foo.bar/page?name={0}&amp;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
Thanks for the feedback, but please note the asp.net-mvc tag. I edited my question to clear things up.
borisCallens
Tags change quickly; I went just by the original question ;-p But fair enough...
Marc Gravell
A: 

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.

hmemcpy
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.
borisCallens
A: 

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

derigel
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...
borisCallens
A: 

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
+1  A: 

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
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.
borisCallens
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
A: 

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