How to convert NameValueCollection to a (Query) String

Most ASP.NET developers know that you can get a key/value pair string from the Request.QueryString object (via the .ToString() method). However that functionality isn’t the same for a generic NameValueCollection object (of which Request.QueryString is derived from).

So how do you take a NameValueCollection object and get a nicely formatted key/value pair string? (i.e. “key1=value1&key2=value2“) … Here’s a method I wrote a while ago:

///

/// Constructs a QueryString (string).
/// Consider this method to be the opposite of "System.Web.HttpUtility.ParseQueryString"
/// 

///
NameValueCollection
/// String
public static String ConstructQueryString(NameValueCollection parameters)
{
	List items = new List();

	foreach (String name in parameters)
		items.Add(String.Concat(name, "=", System.Web.HttpUtility.UrlEncode(parameters[name])));

	return String.Join("&", items.ToArray());
}

Just in case you didn’t know about the System.Web.HttpUtility.ParseQueryString method, it’s a quick way of converting a query (key/value pairs) string back into a NameValueCollection.

18 thoughts on “How to convert NameValueCollection to a (Query) String

  1. Wow I take it back, 6 years and I never noticed that you don’t need the .Keys on a NV collection. :(

  2. Thanks for that! Nice neat method…. Been searching for an easy to use URL encoding facility in .NET.
    And the icing on the cake is that I didn’t even know about the String.Join method – that’s gonna get used time and time again.

    Cheers!

  3. A little flaw in this method – NameValueCollection can contain multiple values for one key – direct indexer like “parameters[name]” will get them concatenated with “,” – instead “parameters.GetValues(name)” should be used

  4. Thanks justonce, I hadn’t thought of separating out the multiple values. I would have just kept them as comma-delimited. But other programming languages/frameworks would handle multiple values differently.

    I’ll re-work the code and update this post (once I get chance).

    Thanks,
    - Lee

  5. Pingback: How to convert NameValueCollection to a (Query) String [Revised] « Lee Kelleher’s Weblog

  6. commas are fine, right? part of the standard.

    Also, save memory

    return String.Join(“&”, from item in collection.AllKeys
    select item + “=” + collection[item]);

    //add urlencode, etc

  7. As I mention at the beginning of my post, .ToString() works for the QueryString object, but not for the NameValueCollection.

  8. ToString works fine if you create the NameValueCollection by calling the HttpUtility.ParseQueryString(). You’ll then get a HttpValueCollection (internal subclass of NameValueCollection), whose ToString nicely concatenates query string and even encodes it for you.

    To get an empty collection just use HttpUtility.ParseQueryString(“”).

  9. Or as an extension method in one line

    public static string AsEncodedQueryString(this NameValueCollection collection)
    {
    return String.Join("&",
    (from string name in collection
    select String.Concat(name, "=", HttpUtility.UrlEncode(collection[name]))).ToArray());
    }

  10. Great Post. Not to beat a dead horse with an old post but using this method you can create a nice and simple ExtensionMethod that works very nicely.

    public static string ConstructQueryString(this System.Collections.Specialized.NameValueCollection Params)
    {
    List items = new List();
    foreach (string name in Params)
    items.Add(String.Concat(name, "=", System.Web.HttpUtility.UrlEncode(Params[name])));
    return string.Join("&", items.ToArray());
    }


    Cheers

  11. Thanks for the great post! I considered doing something wrapped around HttpValueCollection, as recommended by one commentor, but I dislike using private APIs, as they may change without notice. (I also considered the extension method, but, as I work on MANY projects, not all of which I can/should extend built-in APIs, I opted against that too: I prefer consistency to convenience.) I did rework the method you proposed to be pretty much bijective with ParseQueryString (character encoding support), which is below.


    '''
    ''' Builds a URI query string.
    ''' Consider this method to be the converse of "System.Web.HttpUtility.ParseQueryString"
    '''
    ''' NameValueCollection of query string parameters
    ''' Write empty parameter keys to query string
    ''' Query string without leading "?", suitable for use in a UriBuilder
    ''' Original idea from http://blog.leekelleher.com/2008/06/06/how-to-convert-namevaluecollection-to-a-query-string/
    Public Shared Function BuildQueryString(ByRef parameters As NameValueCollection, Optional ByVal includeEmptyValues As Boolean = False) As String
    Return BuildQueryString(parameters, Nothing, includeEmptyValues)
    End Function

    '''
    ''' Builds a URI query string.
    ''' Consider this method to be the converse of "System.Web.HttpUtility.ParseQueryString"
    '''
    ''' NameValueCollection of query string parameters
    ''' Character encoding to use when UrlEncoding parameter keys and values
    ''' Write empty parameter keys to query string
    ''' Query string without leading "?", suitable for use in a UriBuilder
    ''' Original idea from http://blog.leekelleher.com/2008/06/06/how-to-convert-namevaluecollection-to-a-query-string/
    Public Shared Function BuildQueryString(ByRef parameters As NameValueCollection, ByVal e As System.Text.Encoding, Optional ByVal includeEmptyValues As Boolean = False) As String
    Dim l As New List(Of String)
    For Each k As String In parameters.Keys
    Dim v As String = parameters.Item(k)
    If includeEmptyValues Or Not String.IsNullOrWhiteSpace(v) Then
    If e Is Nothing Then
    k = HttpUtility.UrlEncode(k)
    v = HttpUtility.UrlEncode(v)
    Else
    k = HttpUtility.UrlEncode(k, e)
    v = HttpUtility.UrlEncode(v, e)
    End If
    l.Add(String.Format("{0}={1}", k, v))
    End If
    Next

    Return String.Join("&", l)
    End Function

  12. remember to ignore null value when you loop over the collection.

    if you add null values they will appear as empty strings.
    If you then need to parse the qs back to a collection you would get “” instead of null.