I use the following function:
HttpUtility.ParseQueryString
I'm able to extract one parameter value so far. However now I'd like if possible to obtain all parameters in an array, and another array with all their value. Is there a way to do this?
For one parameter value I do this:
HttpUtility.ParseQueryString(myUri.Query).Get(param)
In the worst case, if I can't have an array for both, if I could get a string array for the parameters, I could then use the line above with every parameters to get the value.
You can get dictionary of parameters and then get each parameter value.
string uri = "http://www.example.com?param1=good¶m2=bad";
string queryString = new System.Uri(uri).Query;
var queryDictionary = System.Web.HttpUtility
.ParseQueryString(queryString);
var paramsList = new Dictionary<string, string>();
foreach (var parameter in queryDictionary)
{
var key = (string) parameter;
var value = queryDictionary.Get(key);
paramsList.Add(key, value);
}
Taken from documentation:
NameValueCollection qscoll = HttpUtility.ParseQueryString(querystring);
StringBuilder sb = new StringBuilder("<br />");
foreach (String s in qscoll.AllKeys)
{
sb.Append(s + " - " + qscoll[s] + "<br />");
}
ParseOutput.Text = sb.ToString();
So the result of ParseQueryString is a Dictionary, which holds all parsed data, just iterate through it :)
Related
I would like to find duplicate parameters and then consider the one which has value and eliminate the duplicate one which does not contain value.
Scenario 1 - Suppose I have parameters like firstname, lastname, firstname,middlename
and the value is like firstname=, lastname=con, firstname=abc, middlename=
And
decryptedRequest is something like
lastname=con&firstname=&firstname=abc&middlename=
Scenario 2 - Suppose I have parameters like firstname, lastname, firstname,middlename
and the value is like firstname=test,lastname=con, firstname=abc,middlename=
decryptedRequest is something like
lastname=con&firstname=test&firstname=abc&middlename=
private NameValueCollection parameters;
foreach (var parameter in parameters)
{
if (IsDuplicatedParam(parameter.ToString(), decryptedRequest))
{
LogManager.Publish(LogTypes.Exception | LogTypes.Error, "Duplicate parameter " + parameter + " received in request : " + decryptedRequest);
return false;
}
}
private bool IsDuplicatedParam(string parameter, string decryptedRequest)
{
var requestWithoutParameter = decryptedRequest.Replace(parameter + "=", "");
if (decryptedRequest.Length - requestWithoutParameter.Length > parameter.Length + 1)
return true;
return false;
}
In my first scenario, out of duplicate parameter, it should only return that has value and ignore the duplicate with blank.
Expected output should be, lastname=con, firstname=abc,middlename=
In my second scenario, both duplicate parameters have values so ignore and return and log an error.
Expected output should be, Bad request
But I would like to combine all these logic in my IsDuplicatedParam method.
if there are duplicate parameters and those both parameters have values then return false. But, If either one of the parameter has value then return true. In my code, IsDuplicatedParam() always return true. So I would like to rewrite my IsDuplicatedParam in such a way that it handles my scenarios.
Try this:
parameters.Add("firstname", "");
parameters.Add("lastname", "bbb");
parameters.Add("firstname", "ccc");
IEnumerable<string> pairs =
from key in parameters.Cast<String>()
from value in parameters.GetValues(key).Where(x => x != "").Take(1)
select $"{key}={value}";
Console.WriteLine(String.Join("&", pairs));
That outputs firstname=ccc&lastname=bbb.
you could implement like this.
string str = "lastname=con&firstname=&firstname=abc";
var arr = str.Split('&');
Dictionary<string, string> dict = new Dictionary<string, string>();
for (int i = 0; i < arr.Length; i++)
{
int index = arr[i].IndexOf('=');
string item = arr[i].Substring(0, index);
if (dict.ContainsKey(item) == false)
{
string value = arr[i].Substring(index);
if (value != "=")
dict.Add(item, value);
}
}
It will give you a dictionary with keys as firstname and =con as value. you could modify the cod eif you want to get rid of = in the value
I'm new to C#. I tried to store the value of a dictionary pair in a variable based on if an IF statement evaluates to True, but it's not behaving as I would expect it to. I'm trying to get creative with a project I'm working on and would like to learn how to use dictionaries in this way.
string newFileName = "EOYReportPRF.xls";
string dirInfo_Source = "C:\Temp\"
Dictionary<string, string> fileNameChanges = new Dictionary<string, string>();
fileNameChanges.Add("EOYReportPRF.xls", "EOY_PRF.xls");
fileNameChanges.Add("PayrollEOY.xls", "EOY_SU.xls");
fileNameChanges.Add("PRFFundingStatement.xls", "FS_PRF.xls");
fileNameChanges.Add("SUFundingStatement.xls", "FS_SU.xls");
if (fileNameChanges.ContainsKey(newFileName))
{
File.Move(dirInfo_Source + newFileName, dirInfo_Source + fileNameChanges.Values.ToString());
}
I know that the code is incorrect. I'm just trying to get this to work properly. I want to loop through a directory, passing the name of each file into the newFileName variable. If newFileName matches a key in the dictionary, such as "EOYReportPRF.xls", then I'd like to use the value of the dictionary pair as the file name. Need some help thinking through this. Thanks!
You need to get the actual value for the key:
string newFileName = "EOYReportPRF.xls";
string dirInfo_Source = #"C:\Temp\";
Dictionary<string, string> fileNameChanges = new Dictionary<string, string>();
fileNameChanges.Add("EOYReportPRF.xls", "EOY_PRF.xls");
fileNameChanges.Add("PayrollEOY.xls", "EOY_SU.xls");
fileNameChanges.Add("PRFFundingStatement.xls", "FS_PRF.xls");
fileNameChanges.Add("SUFundingStatement.xls", "FS_SU.xls");
if (fileNameChanges.ContainsKey(newFileName))
{
var filename = fileNameChanges[newFileName];
File.Move(dirInfo_Source + newFileName, dirInfo_Source + filename);
}
That should work.
You may try using TryGetValue method.
string val;
string [] fileEntries = Directory.GetFiles(dirInfo_Source);
foreach(string fileName in fileEntries){
if(fileNameChanges.TryGetValue(fileName, out val)){
File.Move(dirInfo_Source + fileName , dirInfo_Source + val);
}
}
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?
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.
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);
}
}
A lot of the answers are providing custom examples because of the accepted answer's dependency on System.Web. From the Microsoft.AspNet.WebApi.Client NuGet package there is a UriExtensions.ParseQueryString, method that can also be used:
var uri = new Uri("https://stackoverflow.com/a/22167748?p1=6&p2=7&p3=8");
NameValueCollection query = uri.ParseQueryString();
So if you want to avoid the System.Web dependency and don't want to roll your own, this is a good option.
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;
}
To do this without System.Web, without writing it yourself, and without additional NuGet packages:
Add a reference to System.Net.Http.Formatting
Add using System.Net.Http;
Use this code:
new Uri(uri).ParseQueryString()
https://msdn.microsoft.com/en-us/library/system.net.http.uriextensions(v=vs.118).aspx
I needed a function that is a little more versatile than what was provided already when working with OLSC queries.
Values may contain multiple equal signs
Decode encoded characters in both name and value
Capable of running on Client Framework
Capable of running on Mobile Framework.
Here is my solution:
Public Shared Function ParseQueryString(ByVal uri As Uri) As System.Collections.Specialized.NameValueCollection
Dim result = New System.Collections.Specialized.NameValueCollection(4)
Dim query = uri.Query
If Not String.IsNullOrEmpty(query) Then
Dim pairs = query.Substring(1).Split("&"c)
For Each pair In pairs
Dim parts = pair.Split({"="c}, 2)
Dim name = System.Uri.UnescapeDataString(parts(0))
Dim value = If(parts.Length = 1, String.Empty,
System.Uri.UnescapeDataString(parts(1)))
result.Add(name, value)
Next
End If
Return result
End Function
It may not be a bad idea to tack <Extension()> on that too to add the capability to Uri itself.
If you don't want the System.Web dependency, just paste this source code from HttpUtility class.
I just whipped this together from the source code of Mono. It contains the HttpUtility and all it's dependencies (like IHtmlString, Helpers, HttpEncoder, HttpQSCollection).
Then use HttpUtility.ParseQueryString.
https://gist.github.com/bjorn-ali-goransson/b04a7c44808bb2de8cca3fc9a3762f9c
If you want to avoid the dependency on System.Web that is required to use HttpUtility.ParseQueryString, you could use the Uri extension method ParseQueryString found in System.Net.Http.
Make sure to add a reference (if you haven't already) to System.Net.Http in your project.
Note that you have to convert the response body to a valid Uri so that ParseQueryString (in System.Net.Http)works.
string body = "value1=randomvalue1&value2=randomValue2";
// "http://localhost/query?" is added to the string "body" in order to create a valid Uri.
string urlBody = "http://localhost/query?" + body;
NameValueCollection coll = new Uri(urlBody).ParseQueryString();
I just realized that Web API Client has a ParseQueryString extension method that works on a Uri and returns a HttpValueCollection:
var parameters = uri.ParseQueryString();
string foo = parameters["foo"];
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 ] );
}
}
}
Just access Request.QueryString. AllKeys mentioned as another answer just gets you an array of keys.
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);
Since everyone seems to be pasting his solution.. here's mine :-)
I needed this from within a class library without System.Web to fetch id parameters from stored hyperlinks.
Thought I'd share because I find this solution faster and better looking.
public static class Statics
public static Dictionary<string, string> QueryParse(string url)
{
Dictionary<string, string> qDict = new Dictionary<string, string>();
foreach (string qPair in url.Substring(url.IndexOf('?') + 1).Split('&'))
{
string[] qVal = qPair.Split('=');
qDict.Add(qVal[0], Uri.UnescapeDataString(qVal[1]));
}
return qDict;
}
public static string QueryGet(string url, string param)
{
var qDict = QueryParse(url);
return qDict[param];
}
}
Usage:
Statics.QueryGet(url, "id")
Hit up Request.QueryString.Keys for a NameValueCollection of all query string parameters.
To get all Querystring values try this:
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)
Dim sb As New StringBuilder("<br />")
For Each s As String In qscoll.AllKeys
Response.Write(s & " - " & qscoll(s) & "<br />")
Next s
var q = Request.QueryString;
NameValueCollection qscoll = HttpUtility.ParseQueryString(q.ToString());
I translate to C# version of josh-brown in VB
private System.Collections.Specialized.NameValueCollection ParseQueryString(Uri uri)
{
var result = new System.Collections.Specialized.NameValueCollection(4);
var query = uri.Query;
if (!String.IsNullOrEmpty(query))
{
var pairs = query.Substring(1).Split("&".ToCharArray());
foreach (var pair in pairs)
{
var parts = pair.Split("=".ToCharArray(), 2);
var name = System.Uri.UnescapeDataString(parts[0]);
var value = (parts.Length == 1) ? String.Empty : System.Uri.UnescapeDataString(parts[1]);
result.Add(name, value);
}
}
return result;
}
let search = window.location.search;
console.log(search);
let qString = search.substring(1);
while(qString.indexOf("+") !== -1)
qString = qString.replace("+", "");
let qArray = qString.split("&");
let values = [];
for(let i = 0; i < qArray.length; i++){
let pos = qArray[i].search("=");
let keyVal = qArray[i].substring(0, pos);
let dataVal = qArray[i].substring(pos + 1);
dataVal = decodeURIComponent(dataVal);
values[keyVal] = dataVal;
}
This is my code, I think it's very useful:
public String GetQueryString(string ItemToRemoveOrInsert = null, string InsertValue = null )
{
System.Collections.Specialized.NameValueCollection filtered = new System.Collections.Specialized.NameValueCollection(Request.QueryString);
if (ItemToRemoveOrInsert != null)
{
filtered.Remove(ItemToRemoveOrInsert);
if (!string.IsNullOrWhiteSpace(InsertValue))
{
filtered.Add(ItemToRemoveOrInsert, InsertValue);
}
}
string StrQr = string.Join("&", filtered.AllKeys.Select(key => key + "=" + filtered[key]).ToArray());
if (!string.IsNullOrWhiteSpace(StrQr)){
StrQr="?" + StrQr;
}
return StrQr;
}
What's the right syntax to get a BcdObject using ManagementObject? for single parameters I use:
var obj = new ManagementObject(#"root\WMI", string.Format("BcdObject.Id = '{0}'"), null);
But I'm not sure how to add additional parameters (is it AND, or ,, or something else?), something like:
var bcdObj = new ManagementObject(#"root\WMI",
string.Format("BcdObject.Id = '{0}' AND BcdObject.StoreFilePath = '{1}'",
"{current}", ""),
null);
This should be the way to go:
var bcdId = "{current}";
var sfp = "";
var obj = new ManagementObject(
"root\\WMI:BcdObject.Id=\"" + bcdId + "\",StoreFilePath=\"" + sfp + "\"");
Note that even if you merely put a space after the comma it won't work. Good luck!
You can pass the filter string as a second parameter in the constructor (like in your original code) but same rules apply - no spaces.
I've passed a really long Query String from one page to another in my Windows Phone 8 project.
I need to pass these parameters from the new page to another page but don't want to reconstruct he entire QueryString.
Is there a way to assign the entire QueryString to a new String?
Something like
String newQuery = NavigationContext.QueryString.ToString();
I need to pass these parameters from the new page to another page but
don't want to reconstruct the entire QueryString
Why not? This is programming: do all the work in one place so you don't have to do it again later. Let's use an extension method to do this.
Silverlight
Place this code in a static class...
public string ToQueryString(this IDictionary dict)
{
string querystring = "";
foreach(string key in dict.AllKeys)
{
querystring += key + "=" + dict[key] + "&";
}
return querystring;
}
Use it like this...
string QueryString = NavigationContext.QueryString.ToQueryString();
ASP.NET
When I originally read this question, I thought it was for ASP.NET, not Silverlight. I'll leave the ASP.NET answer here in case someone stumbles across it looking for how to do it in ASP.NET.
public string ToQueryString(this NameValueCollection qs)
{
string querystring = "";
foreach(string key in qs.AllKeys)
{
querystring += key + "=" + qs[key] + "&";
}
return querystring;
}
Use it like this...
string QueryString = Request.QueryString.ToQueryString();
There is something that already exists for ASP.NET. But I feel it's important to demonstrate that you can do all the work once somewhere. Then not have to do it again. If you want to use a built-in way, something like this would work, using the Query property of the Uri class.
string QueryString = System.Web.HttpContext.Current.Request.Url.Query;
Here's a way that may be a little simpler...
You could project the results into a format of your choosing. Here's a simple example below.
I've used an IDictionary<string,string> as it is the underlying type for NavigationContext.QueryString
var test = new Dictionary<String,String>();
test.Add("1", "one");
test.Add("2", "two");
test.Add("3", "three");
// Choose any string format you wish and project to array
var newArray = test.Select(item => item.Key + ":" + item.Value).ToArray();
// Join on any separator
string output = String.Join(",", newArray);
This still means that you have to interpret the result later (according to the format you chose). Here you'll get a format like
"1:one,2:two,3:three"
If you've sent it as a querystring just pull it back out on the OnNavigatedTo() Method and then you can store the query in the page until you move on?.
string newQuery;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
newQuery = NavigationContext.QueryString["queryName"];
}
Try this:
public string GetQueryString()
{
IDictionary<String, String> NavigationContextData = NavigationContext.QueryString;
string data = "/Pagename.xaml?";
foreach (var item in NavigationContextData)
{
data += item.Key + "=" + item.Value + "&";
}
data = data.Substring(0, data.Length - 1);
return data;
}
If it's in your OnNavigatedTo() event, you can use a quick, easy two-liner. This can be condensed to a single line or expanded to check for the existence of the ? character. If you know that there are always parameters passed, the check is unnecessary and these two lines work fine:
string QStr = e.Uri.ToString();
string ParmStr = QStr.Substring(QStr.IndexOf('?') + 1);
You can also condense it into a single line:
string ParmStr = e.Uri.ToString().Substring(e.Uri.ToString().IndexOf('?') + 1);