Easiest Way to Parse "Querystring" Formatted Data

Parse and modify a query string in .NET Core

If you are using ASP.NET Core 1 or 2, you can do this with Microsoft.AspNetCore.WebUtilities.QueryHelpers in the Microsoft.AspNetCore.WebUtilities package.

If you are using ASP.NET Core 3.0 or greater, WebUtilities is now part of the ASP.NET SDK and does not require a separate nuget package reference.

To parse it into a dictionary:

var uri = new Uri(context.RedirectUri);
var queryDictionary = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query);

Note that unlike ParseQueryString in System.Web, this returns a dictionary of type IDictionary<string, string[]> in ASP.NET Core 1.x, or IDictionary<string, StringValues> in ASP.NET Core 2.x or greater, so the value is a collection of strings. This is how the dictionary handles multiple query string parameters with the same name.

If you want to add a parameter on to the query string, you can use another method on QueryHelpers:

var parametersToAdd = new System.Collections.Generic.Dictionary<string, string> { { "resource", "foo" } };
var someUrl = "http://www.google.com";
var newUri = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(someUrl, parametersToAdd);

Using .net core 2.2 you can get the query string using

var request = HttpContext.Request;
var query = request.Query;
foreach (var item in query){
Debug.WriteLine(item)
}

You will get a collection of key:value pairs - like this

[0] {[companyName, ]}
[1] {[shop, ]}
[2] {[breath, ]}
[3] {[hand, ]}
[4] {[eye, ]}
[5] {[firstAid, ]}
[6] {[eyeCleaner, ]}

How to parse a query string into a NameValueCollection in .NET

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)

You may need to replace querystring with new Uri(fullUrl).Query.

Convert querystring from/to object

You can use reflection, something like this:

public T GetFromQueryString<T>() where T : new(){
var obj = new T();
var properties = typeof(T).GetProperties();
foreach(var property in properties){
var valueAsString = HttpContext.Current.Request.QueryString[property.PropertyName];
var value = Parse( valueAsString, property.PropertyType);

if(value == null)
continue;

property.SetValue(obj, value, null);
}
return obj;
}

You'll need to implement the Parse method, just using int.Parse, decimal.Parse, DateTime.Parse, etc.

Parse a URI String into Name-Value Collection

If you are looking for a way to achieve it without using an external library, the following code will help you.

public static Map<String, String> splitQuery(URL url) throws UnsupportedEncodingException {
Map<String, String> query_pairs = new LinkedHashMap<String, String>();
String query = url.getQuery();
String[] pairs = query.split("&");
for (String pair : pairs) {
int idx = pair.indexOf("=");
query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
}
return query_pairs;
}

You can access the returned Map using <map>.get("client_id"), with the URL given in your question this would return "SS".

UPDATE URL-Decoding added

UPDATE As this answer is still quite popular, I made an improved version of the method above, which handles multiple parameters with the same key and parameters with no value as well.

public static Map<String, List<String>> splitQuery(URL url) throws UnsupportedEncodingException {
final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
final String[] pairs = url.getQuery().split("&");
for (String pair : pairs) {
final int idx = pair.indexOf("=");
final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
if (!query_pairs.containsKey(key)) {
query_pairs.put(key, new LinkedList<String>());
}
final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null;
query_pairs.get(key).add(value);
}
return query_pairs;
}

UPDATE Java8 version

public Map<String, List<String>> splitQuery(URL url) {
if (Strings.isNullOrEmpty(url.getQuery())) {
return Collections.emptyMap();
}
return Arrays.stream(url.getQuery().split("&"))
.map(this::splitQueryParameter)
.collect(Collectors.groupingBy(SimpleImmutableEntry::getKey, LinkedHashMap::new, mapping(Map.Entry::getValue, toList())));
}

public SimpleImmutableEntry<String, String> splitQueryParameter(String it) {
final int idx = it.indexOf("=");
final String key = idx > 0 ? it.substring(0, idx) : it;
final String value = idx > 0 && it.length() > idx + 1 ? it.substring(idx + 1) : null;
return new SimpleImmutableEntry<>(
URLDecoder.decode(key, StandardCharsets.UTF_8),
URLDecoder.decode(value, StandardCharsets.UTF_8)
);
}

Running the above method with the URL

https://stackoverflow.com?param1=value1¶m2=¶m3=value3¶m3

returns this Map:

{param1=["value1"], param2=[null], param3=["value3", null]}

How can I get query string values in JavaScript?

Update: Jan-2022

Using Proxy() is faster than using Object.fromEntries() and better supported

const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
// Get the value of "some_key" in eg "https://example.com/?some_key=some_value"
let value = params.some_key; // "some_value"

Update: June-2021

For a specific case when you need all query params:

const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());

Update: Sep-2018

You can use URLSearchParams which is simple and has decent (but not complete) browser support.

const urlParams = new URLSearchParams(window.location.search);
const myParam = urlParams.get('myParam');

Original

You don't need jQuery for that purpose. You can use just some pure JavaScript:

function getParameterByName(name, url = window.location.href) {
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

Usage:

// query string: ?foo=lorem&bar=&baz
var foo = getParameterByName('foo'); // "lorem"
var bar = getParameterByName('bar'); // "" (present with empty value)
var baz = getParameterByName('baz'); // "" (present with no value)
var qux = getParameterByName('qux'); // null (absent)

NOTE: If a parameter is present several times (?foo=lorem&foo=ipsum), you will get the first value (lorem). There is no standard about this and usages vary, see for example this question: Authoritative position of duplicate HTTP GET query keys.

NOTE: The function is case-sensitive. If you prefer case-insensitive parameter name, add 'i' modifier to RegExp

NOTE: If you're getting a no-useless-escape eslint error, you can replace name = name.replace(/[\[\]]/g, '\\$&'); with name = name.replace(/[[\]]/g, '\\$&').


This is an update based on the new URLSearchParams specs to achieve the same result more succinctly. See answer titled "URLSearchParams" below.

How to split a string for key value pairs and save them to a dictionary?

It looks like you are trying to split a query string into a dictionary of query parameters. You should be able to use the HttpUtility.ParseQueryString method. Note that this method returns a NameValueCollection. That object will probably work for you, but if you need a Dictionary, you can use a simple for loop to convert the NameValueCollection to a Dictionary.

Also, if you decide for whatever reason to stick with your original code, you can greatly simplify this code:

switch (param[0].ToUpper())
{
case "TEST1":
dict.Add("TEST1", param[1]);
break;
case "TEST2":
dict.Add("TEST2", param[1]);
break;
case "TEST3":
dict.Add("TEST3", param[1]);
break;
}

You don't need a separate case for each possible value. Instead, you can simply write this:

dict.Add(param[0].ToUpper(), param[1]);


Related Topics



Leave a reply



Submit