AndyH
AndyH

Reputation:

Best way to convert query string to dictionary in C#

I'm looking for the simplest way of converting a query string from an HTTP GET request into a Dictionary, and back again.

I figure it's easier to carry out various manipulations on the query once it is in dictionary form, but I seem to have a lot of code just to do the conversion. Any recommended ways?

Upvotes: 84

Views: 72772

Answers (14)

KyleMit
KyleMit

Reputation: 29909

AspNet Core now automatically includes HttpRequest.Query which can be used similar to a dictionary with key accessors like this:

var x = Current.Request.Query["x"];

However if you needed to cast it for logging or other purposes, you can pull out that logic into an extension method like this:

public static class HttpRequestExtensions
{
  public static Dictionary<string, string> ToDictionary(this IQueryCollection query)
  {
    return query.Keys.ToDictionary(k => k, v => (string)query[v]);
  }
}

Then, you can consume it on your httpRequest like this:

var queryParams = Current.Request.Query.ToDictionary()

Further Reading

Upvotes: 1

blackboxlogic
blackboxlogic

Reputation: 588

Instead of converting HttpContext.Request.QueryString to Dictionary<>, try using

HttpContext.Request.Query

which already is a Dictionary<string, StringValues>

Upvotes: 1

H7O
H7O

Reputation: 889

Here is how I usually do it

Dictionary<string, string> parameters = HttpContext.Current.Request.QueryString.Keys.Cast<string>()
    .ToDictionary(k => k, v => HttpContext.Current.Request.QueryString[v]);

Upvotes: 46

Mendy
Mendy

Reputation: 8642

You can just get it by decorating the parameter with the FromQueryAttribute

public void Action([FromQuery] Dictionary<string, string> queries)
{
    ...
}

P.S. If you want to get multiple values for each key you can change the Dictionary to Dictionary<string, List<string>>

Upvotes: 2

David B
David B

Reputation: 929

I stumbled across this post whilst looking for the same solution for an Azure WebJob, hopefully this helps others doing the same.

If you are coding an Azure WebJob you use the GetQueryParameterDictionary() extension method.

var queryParameterDictionary = request.GetQueryParameterDictionary();

where request is of type HttpRequest and queryParameterDictionary is now of type IDictionary<string, string>

Upvotes: 1

James Lawruk
James Lawruk

Reputation: 31345

In ASP.NET Core, use ParseQuery.

var query = HttpContext.Request.QueryString.Value;
var queryDictionary = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(query);

Upvotes: 10

Bruno Leit&#227;o
Bruno Leit&#227;o

Reputation: 811

Most simple:

Dictionary<string, string> parameters = new Dictionary<string, string>();

for (int i = 0; i < context.Request.QueryString.Count; i++)
{
    parameters.Add(context.Request.QueryString.GetKey(i), context.Request.QueryString[i]);
}

Upvotes: 1

ThisGuy
ThisGuy

Reputation: 2385

Same as Sean, but with Linq (and a function you can copy and paste):

public static Dictionary<string, string> ParseQueryString(string queryString)
{
   var nvc = HttpUtility.ParseQueryString(queryString);
   return nvc.AllKeys.ToDictionary(k => k, k => nvc[k]);
}

Also, the question asked how to get it back into a query string:

public static string CreateQueryString(Dictionary<string, string> parameters)
{
   return string.Join("&", parameters.Select(kvp => 
      string.Format("{0}={1}", kvp.Key, HttpUtility.UrlEncode(kvp.Value))));
}

Upvotes: 20

Sean Colombo
Sean Colombo

Reputation: 1519

Yet another way to do it:

NameValueCollection nvcData = HttpUtility.ParseQueryString(queryString);
Dictionary<string, string> dictData = new Dictionary<string, string>(nvcData.Count);
foreach (string key in nvcData.AllKeys)
{
    dictData.Add(key, nvcData.Get(key));
}

Upvotes: 6

vicentedealencar
vicentedealencar

Reputation: 933

One liner without HttpUtility

var dictionary = query.Replace("?", "").Split('&').ToDictionary(x => x.Split('=')[0], x => x.Split('=')[1]);

Upvotes: 8

JWL
JWL

Reputation: 14201

I like the brevity of Jon Canning's answer, but in the interest of variety, here is another alternative to his answer, that would also work for restricted environments like Windows Phone 8, that lack the HttpUtility.ParseQueryString() utility:

    public static Dictionary<string, string> ParseQueryString(String query)
    {
        Dictionary<String, String> queryDict = new Dictionary<string, string>();
        foreach (String token in query.TrimStart(new char[] { '?' }).Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries))
        {
            string[] parts = token.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length == 2)
                queryDict[parts[0].Trim()] = HttpUtility.UrlDecode(parts[1]).Trim();
            else
                queryDict[parts[0].Trim()] = "";
        }
        return queryDict;
    }

Actually, a useful improvement to Canning's answer that take care of decoding url-encoded values (like in the above solution) is:

    public static Dictionary<string, string> ParseQueryString2(String query)
    {
       return Regex.Matches(query, "([^?=&]+)(=([^&]*))?").Cast<Match>().ToDictionary(x => x.Groups[1].Value, x => HttpUtility.UrlDecode( x.Groups[3].Value ));
    }

Upvotes: 7

Jon Canning
Jon Canning

Reputation: 1642

Just had to do this for a mono compatible solution

Regex.Matches(queryString, "([^?=&]+)(=([^&]*))?").Cast<Match>().ToDictionary(x => x.Groups[1].Value, x => x.Groups[3].Value)

Upvotes: 14

Anton Gogolev
Anton Gogolev

Reputation: 115741

HttpUtility.ParseQueryString() parses query string into a NameValueCollection object, converting the latter to an IDictionary<string, string> is a matter of a simple foreach. This, however, might be unnecessary since NameValueCollection has an indexer, so it behaves pretty much like a dictionary.

Upvotes: 75

Marc Gravell
Marc Gravell

Reputation: 1062770

How about HttpUtility.ParseQueryString?

Just add a reference to System.Web.dll

Upvotes: 22

Related Questions