24

I'm working with a page where I have a url like:
/directory/company/manufacturer

Using some re-write rules this gets re-written

testing with /directory/company/dunkin%26donuts/

Some manufacturers have an ampersand in their name. So I thought I could just replace the ampersand with %26. However, when I debug the code and hover over Request.QueryString it shows me {qq=company&manf=dunkin&donuts&cond=} and Request.QueryString["manf"] gives me 'dunkin'

If I use %24 ($) instead of ampersand, hovering over Request.QueryString gives me {qs=company&manf=dunkin%24donuts&cond=} and Request.QueryString["manf"] gives me 'dunkin$donuts'

I don't understand the different behavior here. Why does it seem as though the url-encoded value for an ampersand gets decoded before you actually request a specific key, but another url-encoded character, like a dollar sign, only gets decoded after you actually request that specific key?

Is this a recent change? I always thought Request.QueryString[key] returned the actual text without decoding it first. Or does it have something to do with url re-writes?

Mathew Thompson
  • 55,877
  • 15
  • 127
  • 148
merk
  • 1,721
  • 5
  • 23
  • 39

3 Answers3

43

ASP.NET automatically calls UrlDecode() when you access a property by key index (i.e. (Request.QueryString["key"]).

If you want it encoded, just do:

HttpUtility.UrlEncode(Request.QueryString["key"]);

In terms of the ampersand specifically, that is a special case character because it is already used as a query string delimeter. URL Encoding and decoding an ampersand should always give you & for that very reason.

Mathew Thompson
  • 55,877
  • 15
  • 127
  • 148
  • 1
    @StriplingWarrior I think I only answered half of his question looking back, I've edited to include why exactly ampersands are different. – Mathew Thompson Oct 26 '12 at 23:06
  • I realize it's a special character - i just dont understand why it seems to be getting decoded at a different point then compared to the dollar sign. When i hover over Request.QueryString in VS2010 while debugging the page, i see the urlencoded value for the dollar sign - %24. But when it comes to the ampersand, i always see the decoded value. – merk Oct 27 '12 at 00:20
  • Is there a reference to a MSDN article stating that the UrlDecode is automatically called? – MADCookie Feb 20 '14 at 00:28
  • @MADCookie I don't know buddy, but if you try debugging it yourself you'll see for sure (that's what I did) :) – Mathew Thompson Feb 20 '14 at 11:00
  • Debugging is what i've been doing and, yes, I see the value from Request("blah") where blah=Some%2fValue is giving me Some/Value. I just want to hear it from the horse's mouth before I direct my team mates to make a change. This is ignoring the question: what other magic is taking place? What encoding magic is on the Response object? – MADCookie Feb 20 '14 at 20:16
  • Problem with this is if you do want special characters in the querystring. For example I am using ';' to separate a list of values, sometimes those values contain ampersands. When referring to that querystring with Request.Querystring[key] it replaces %26 with an ampersand. UrlEncoding that keeps my ampersand as a %26 but converts my ';' to %3b, thus loosing my separators. – Tod Oct 20 '14 at 10:34
  • See: https://msdn.microsoft.com/en-us/library/system.web.httprequest.querystring(v=vs.110).aspx – 76484 Aug 12 '16 at 01:02
10

Replacing the ampersand with %26 should cause that value to be escaped, so Request.QueryString["manf"] would yield dunkin&donuts.

The asker of this similar question ended up realizing that some other code on the same page ended up pre-decoding his ampersands. Is it possible that you've got something similar happening? Perhaps some javascript is decoding the %26 into an ampersand before sending it to your server. Try using Firebug or Chrome's developer tools to see the actual URL string that is being sent from the browser.

Update

After looking at the question again, I realize that you're probably using a URL Rewriter. This post describes a similar problem, and I don't know of a solution for sure, but you may want to try double-encoding the ampersand using %2526 instead of %26.

Community
  • 1
  • 1
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • It's possible something else is playing with the url - either the rewrite or maybe some other pre-existing code on the site. This isn't a site I created but one i took over from someone else. So there might be some other code involved here. Hadn't thought of that. I'll do some digging. thanks. I'll update this question once i have more info – merk Oct 27 '12 at 00:21
  • dbl encoding didnt work btw - dunkin%2526donuts got turned into dunkin&25donuts – merk Oct 27 '12 at 00:24
  • Not sure what changed, but your suggestion for dbl encoding seems to be working now. I actually tried doing it like %25%32%36, which also worked. but then the browser i think auto-converted that to %2526 and it started working – merk Oct 27 '12 at 00:51
  • @merk: You probably did %2625 the first time. – StriplingWarrior Oct 29 '12 at 15:28
3

I think a solution might be to modify the UrlRewrite rule to something like.

    <rule name="TagPage" stopProcessing="true">
      <match url="^(tag)/([^/]+)/?$"/>
      <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
      </conditions>
      <action type="Rewrite" url="ListByTags.aspx?tag={UrlEncode:{R:2}}"/>
    </rule>

The important line here is the {UrlEncode:{R:2}}. It solved the problem for me!

Olaj
  • 1,782
  • 4
  • 19
  • 36