39

Is there any function that converts an escaped Url string to its unescaped form? System.Web.HttpUtility.UrlDecode() can do that job but I don't want to add a reference to System.Web.dll. Since my app is not a web application, I don't want to add a dependency for only using a function in an assembly.

UPDATE: Check Rick Strahl's blog post about the same issue.

Michał Powaga
  • 22,561
  • 8
  • 51
  • 62
huseyint
  • 14,953
  • 15
  • 56
  • 78
  • 1
    Rick Strahl's post is a must read - it contains the necessary background and an in depth analysis of the different solutions the .NET framework offers (or doesn't offer). – Oliver May 17 '13 at 12:16
  • Possible duplicate of [How do I decode a URL parameter using C#?](http://stackoverflow.com/questions/1405048/how-do-i-decode-a-url-parameter-using-c) – Michael Freidgeim Apr 17 '17 at 10:00

9 Answers9

72

EDIT: Use the static method Uri.UnescapeDataString() to decode your URLs:

Encoded: http%3a%2f%2fwww.google.com%2fsearch%3fhl%3den%26q%3dsomething%20%2323%26btnG%3dGoogle%2bSearch%26aq%3df%26oq%3d

Decoded: http://www.google.com/search?hl=en&q=something #23&btnG=Google+Search&aq=f&oq=

Igal Tabachnik
  • 31,174
  • 15
  • 92
  • 157
  • this dosen't to work for me it just returns the original string pass to the `Uri.UnescapeDataString(myurl)` – Smith Jun 29 '11 at 13:01
  • 7
    Beware: This doesn't work for plus signs - http://blogs.msdn.com/b/yangxind/archive/2006/11/09/don-t-use-net-system-uri-unescapedatastring-in-url-decoding.aspx I'm still looking for a better method. – Chris Weber Aug 02 '12 at 20:54
  • 3
    @Chris: Rick Strahl built a utility class around `Uri.UnescapeDataString()` that handles the `+` signs correctly. See [his blog post](http://www.west-wind.com/weblog/posts/617930.aspx) for more detail. – Oliver May 17 '13 at 12:15
  • Four years later -- I _think_ `UnescapeDataString` handles plus signs now. https://repl.it/repls/MildGlossyPorts – Michael Armes Jul 31 '19 at 14:56
7

If you are using .NET 4.0 or later, you can use WebUtility.UrlDecode which works with client profile and also correctly processes plus signs.

Lirrik
  • 795
  • 11
  • 17
4

Re not loading System.Web.dll - as others have noted, it isn't worth getting excited unless you know that you need to deal with clients that might not have it ("client profile", "compact framework", "micro framework", "silverlight").

Re space; it won't be a lot really; note that .NET assemblies are JITted on a method-by-method basis, so there won't be any significant overhead just from using a few methods.

The real issue (IMO) is your level of confidence that the client has System.Web.dll; if you are happy that they are using the full framework, then just go for it.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
2

@Smith
I was having the save problem. No changes or just further jumbling.

After testing many things I noticed a test string did decode. Ultimately I had to create a new empty string, set it's value to the encoded string then run WebUtility.HtmlDecode and Uri.UnescapeDataString on the new string. For some reason I had to run the decode and unescape in the order I mentioned. Bizarre.

I solved it with something like this.

Dim strEncoded as string="http%3a%2f%2fwww.google.com%2fsearch%3fhl%3den%26q%3dsomething%20%2323%26btnG%3dGoogle%2bSearch%26aq%3df%26oq%3d"

Dim strDecoded as string = ""
strDecoded = strEncoded
strDecoded = WebUtility.HtmlDecode(strDecoded)
strDecoded = Uri.UnescapeDataString(strDecoded)
Michał Powaga
  • 22,561
  • 8
  • 51
  • 62
DaveCS
  • 950
  • 1
  • 10
  • 16
0

The Microsoft ACE team have an extended (and better) version of decode, in the Anti-XSS library. However I'm not sure if it just passes through.

(I don't see why you're that worried about the dependency on System.web.dll to be honest)

blowdart
  • 55,577
  • 12
  • 114
  • 149
  • The reason is that I don't want to load a rather large DLL into my memory space for the sake of only one method call. It would be good if someone points an implementation (probably uses Regex) that I can copy/paste into my project. – huseyint Oct 27 '08 at 11:15
  • A regex solution is not going to be enough; decoding is *hard*. If you're really worried then, *cough*, reflector. Have you actually looked at the memory cost of loading the assembly? It's probably not as large as you think. – blowdart Oct 27 '08 at 11:52
  • 1
    Note that different framework versions (esp. "client profile") are a valid reason to avoid it - but not worth getting *too* excited over it ;-p – Marc Gravell Oct 27 '08 at 12:03
  • Actually, the AntiXss library does not provide the decoding methods, only encoding. – Igal Tabachnik Oct 27 '08 at 12:37
0

You already have a HUGE dependency on the .NET framework, CLR etal. So, in fact, you already have an indirect dependency on System.Web.DLL; your application CAN NOT RUN without its presence on the local machine.

And you're worried about memory? Do you have memory issues? If you have memory issues so extreme you can't load a couple KBs of DLL into your app's memory, then why are you coding .NET? Or are you just prematurely optimizing?

So don't worry about it.

  • 5
    Your assertion is incorrect; "client profile", "cf" and "silverlight" will all lack System.Web.dll; "client profile" is a version of regular .NET, so is the most striking. – Marc Gravell Oct 27 '08 at 11:59
  • 1
    @marc iirc when this was answered the client profiles weren't released/commonly known about. Second, he doesn't say what kind of app, and in fact from the way he asks the question its obvious that it IS an option to reference system.web.dll. Otherwise the question is moot. So my assertation is most likely correct. Nyah. –  Mar 04 '10 at 17:52
0

Just a little understanding of why it's different. One converts to uppercase and one converts to lowercase. So the decode is specific to the type of encode.

System.Net.WebUtility (Internal) + 65:

private static char IntToHex(int n)
{
    if (n <= 9)
        return (char) (n + 48);
    else
        return (char) (n - 10 + 65);
}

System.Web.Util.HttpEncoderUtility (Internal) - + 97

public static char IntToHex(int n)
{
    if (n <= 9)
        return (char) (n + 48);
    else
        return (char) (n - 10 + 97);
}

Example:

var test1 = WebUtility.UrlEncode("http://www.test.com/?param1=22&param2=there@is<a space");
var test2 = HttpUtility.UrlEncode("http://www.test.com/?param1=22&param2=there@is<a space");

Response:

test1 -> http%3A%2F%2Fwww.test.com%2F%3Fparam1%3D22%26param2%3Dthere%40is%3Ca+space
test2 -> http%3a%2f%2fwww.test.com%2f%3fparam1%3d22%26param2%3dthere%40is%3ca+space

More information....

Chizl
  • 2,004
  • 17
  • 32
0

In Android this fixed the issue, It took me few hours to figure out, I hope I am saving your time now

val objectRequest = GetObjectRequest(s3Uri.bucket, S3HttpUtils.urlDecode(s3Uri.key))
murali kurapati
  • 1,510
  • 18
  • 23
-3

System.Net.WebUtility.HtmlDecode is also working on .NET 4.0 Client Profile.

Michał Powaga
  • 22,561
  • 8
  • 51
  • 62
Zibri
  • 9,096
  • 3
  • 52
  • 44