3

I need parse query string: ?artist=singer1 & singer2&song=name song

Static method HttpUtility.ParseQueryString doesn't work the way I want if value contains ampersand like "singer1 & singer2".

For example:

string qs = "?artist=singer1 & singer2&song=name song"; 
NameValueCollection query = HttpUtility.ParseQueryString(qs);

Result is:

  1. artist = singer1
  2. null = singer2
  3. song = name song

I would like result

artist = singer 1 & singer2
song = name song

Any idea?

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
misak
  • 342
  • 1
  • 2
  • 13
  • And what result did you expect? – cdhowie Mar 22 '13 at 14:23
  • 12
    HttpUtility.ParseQueryString work corectly, your query string is incorrect, each parament MUST have both name and value – Alex Mar 22 '13 at 14:23
  • Errr - what were you expecting? The posted results look right to me... – RB. Mar 22 '13 at 14:24
  • 2
    Actually, `&singer2&` should be parsed as `singer2=`, not the other way around. – Lasse V. Karlsen Mar 22 '13 at 14:24
  • `&` is a reserved symbol use another symbol to combine singer1 to singer2 – anouar.bagari Mar 22 '13 at 14:25
  • @LasseV.Karlsen I suspect that it is and the OP wrote it down backwards. – cdhowie Mar 22 '13 at 14:25
  • what do you mean 'doesnt work correctly'? the query string has two parts e.g. 'artist=singer', your 'singer2' does not have the first part, that is why its `null`. – robasta Mar 22 '13 at 14:25
  • Those spaces don't look very good. Shouldn't they be encoded? From the RFC : "The space character is unsafe because significant spaces may disappear and insignificant spaces may be introduced when URLs are transcribed or typeset or subjected to the treatment of word-processing programs" – spender Mar 22 '13 at 14:26
  • 1
    @cdhowie Actually, it seems HttpUtility parses it incorrect, it does indeed give it the name `null`. – Lasse V. Karlsen Mar 22 '13 at 14:27
  • @LasseV.Karlsen Hah, that's rather bizarre... – cdhowie Mar 22 '13 at 14:28
  • Closed as duplicate for standard http://stackoverflow.com/questions/68624/how-to-parse-a-query-string-into-a-namevaluecollection-in-net as this particular one really caused by invalid expectations/invalid string passed from client. There is nothing wrong with ParseQueryString. – Alexei Levenkov Sep 02 '16 at 03:20

3 Answers3

15

The ampersand (&) in the middle of one of your values is throwing off the parser since it's a reserved symbol. Replace it with its numeric code instead:

string qs = "?artist=singer1+%26+singer2&song=name song"; 
NameValueCollection query = HttpUtility.ParseQueryString(qs);
cdhowie
  • 158,093
  • 24
  • 286
  • 300
D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • Thanks, client application send me incorrect query string. – misak Mar 22 '13 at 14:53
  • [How to build a query string for a URL in C#?](http://stackoverflow.com/questions/829080/how-to-build-a-query-string-for-a-url-in-c) is good place to copy code to build urls. – Alexei Levenkov Sep 02 '16 at 03:30
6

Your problem is that & carries special meaning in a query string, namely to separate arguments. The & in the middle of your perceived artist parameter is actually being parsed as an argument separator. You need to URL encode the & when constructing the URL.

For example, one correct query string would be:

?artist=singer1+%26+singer2&song=name+song

(Spaces can usually be encoded either as + or %20, but that's a topic for another discussion.)

You can use HttpUtility.UrlEncode() when building the query string components to ensure that the result is correctly escaped. For example, you could build the query string like this:

static void Main()
{
    var values = new NameValueCollection();
    values["artist"] = "singer1 & singer2";
    values["song"] = "name song";

    Console.WriteLine(CreateQueryString(values));
}

static string CreateQueryString(NameValueCollection values)
{
    if (values == null) { throw new ArgumentNullException("values"); }

    return string.Join(
        "&",
        values.AllKeys.Select(key => HttpUtility.UrlEncode(key) + "=" +
                                     HttpUtility.UrlEncode(values[key]))
                      .ToArray());
}

In other words, the issue is occuring at the time you build the query string, not when you are trying to parse it. When parsing it you already have a semantically incorrect query string; there's nothing you can do at this point.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
0

If you want artist = singer1 & singer2 you need to escape or encode the & in your query string.

for example, if I ask Google about fred & blotts the resulting query string contains &q=fred+%26+blotts rather than &q=fred+&+blotts

See https://www.rfc-editor.org/rfc/rfc3986#page-12

Community
  • 1
  • 1
Denise Skidmore
  • 2,286
  • 22
  • 51