I would like to parse a string such as "p1=6&p2=7&p3=8" into a NameValueCollection.

What is the most elegant way of doing this when you don't have access to the Page.Request object?

share|improve this question

7 Answers

up vote 170 down vote accepted

There's a built-in .NET utility for this: HttpUtility.ParseQueryString

// C#
NameValueCollection qscoll = HttpUtility.ParseQueryString(querystring);
' VB.NET
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)
share|improve this answer
Note: PraseQueryString will successfully parse a full URL (http://stackoverflow.com?para=yes). You don't have to pass just the query string part. – Omar Mar 22 '11 at 16:50
12  
Omar, it didn't work for me on ASP.NET 4, it returned a key of "stackoverflow.com?para"; instead of "para". So I'm using HttpUtility.ParseQueryString(new Uri(fullUrl).Query) which correctly works for me. – Michael Apr 5 '11 at 22:01
qscoll["p1"] , qscoll["p2"] and qscoll["p3"] – LifeH2O Sep 1 '11 at 20:28
3  
ParseQueryString is really poor idea to use in desktop application, because it isn't included in Client Profile; why to install 100 M of additional libraries on client computer to just use one simple method? However, it looks like Microsoft doesn't have any better idea. The only way is to implement own method or use open source implementation. – VASoftOnline Jun 1 '12 at 12:05
VASoftOnline: In that case you can use the Mono implementation of ParseQueryString: github.com/mono/mono/blob/master/mcs/class/System.Web/… the license for that is MIT X11:github.com/mono/mono/blob/master/LICENSE – sw. Jan 4 at 17:09

HttpUtility.ParseQueryString will work as long as you are in a web app or don't mind including a dependency on System.Web. Another way to do this is:

NameValueCollection queryParameters = new NameValueCollection();
string[] querySegments = queryString.Split('&');
foreach(string segment in querySegments)
{
   string[] parts = segment.Split('=');
   if (parts.Length > 0)
   {
      string key = parts[0].Trim(new char[] { '?', ' ' });
      string val = parts[1].Trim();

      queryParameters.Add(key, val);
   }
}
share|improve this answer
14  
Don't forget to "url decode" the parameter values. – C. Dragon 76 Nov 9 '10 at 0:15

I wanted to remove the dependency on System.Web so that I could parse the query string of a ClickOnce deployment, while having the prerequisites limited to the "Client-only Framework Subset".

I liked rp's answer. I added some additional logic.

public static NameValueCollection ParseQueryString(string s)
    {
        NameValueCollection nvc = new NameValueCollection();

        // remove anything other than query string from url
        if(s.Contains("?"))
        {
            s = s.Substring(s.IndexOf('?') + 1);
        }

        foreach (string vp in Regex.Split(s, "&"))
        {
            string[] singlePair = Regex.Split(vp, "=");
            if (singlePair.Length == 2)
            {
                nvc.Add(singlePair[0], singlePair[1]);
            }
            else
            {
                // only one key with no value specified in query string
                nvc.Add(singlePair[0], string.Empty);
            }
        }

        return nvc;
    }
share|improve this answer

Just access Request.QueryString. AllKeys mentioned as another answer just gets you an array of keys.

share|improve this answer

Hit up Request.QueryString.Keys for a NameValueCollection of all query string parameters.

share|improve this answer
    private void button1_Click( object sender, EventArgs e )
    {
        string s = @"p1=6&p2=7&p3=8";
        NameValueCollection nvc = new NameValueCollection();

        foreach ( string vp in Regex.Split( s, "&" ) )
        {
            string[] singlePair = Regex.Split( vp, "=" );
            if ( singlePair.Length == 2 )
            {
                nvc.Add( singlePair[ 0 ], singlePair[ 1 ] );    
            }    
        }
    }
share|improve this answer
2  
Doh! Thank you Guy Starbuck. I hate it when I work too hard. – rp. Sep 16 '08 at 2:01
4  
semicolon is also allowed as a parameter separator in http, better not to reinvent the wheel – Matthew Lock Oct 28 '09 at 7:14

HttpUtility.ParseQueryString(Request.Url.Query) return is HttpValueCollection (internal class). It inherits from NameValueCollection.

    var qs = HttpUtility.ParseQueryString(Request.Url.Query);
    qs.Remove("foo"); 

    string url = "~/Default.aspx"; 
    if (qs.Count > 0)
       url = url + "?" + qs.ToString();

    Response.Redirect(url); 
share|improve this answer

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.