Reputation:
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
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
Reputation: 588
Instead of converting HttpContext.Request.QueryString
to Dictionary<>
, try using
HttpContext.Request.Query
which already is a Dictionary<string, StringValues>
Upvotes: 1
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
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
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
Reputation: 31345
In ASP.NET Core, use ParseQuery.
var query = HttpContext.Request.QueryString.Value;
var queryDictionary = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(query);
Upvotes: 10
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
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
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
Reputation: 933
One liner without HttpUtility
var dictionary = query.Replace("?", "").Split('&').ToDictionary(x => x.Split('=')[0], x => x.Split('=')[1]);
Upvotes: 8
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
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
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
Reputation: 1062770
How about HttpUtility.ParseQueryString
?
Just add a reference to System.Web.dll
Upvotes: 22