Assign the entire QueryString to a String? - c#

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);

Related

Easier way to extract ID from a string? [duplicate]

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;
}

How to get every parameters and their value?

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&param2=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 :)

C# TextBox Form Email Object Simplification

I have a huge webform with many textboxes and on client click, the data needs to be emailed to the company.
At present I am hard coding and concatenating the message body with direct references to the various textboxes, however this is a lot of typing and would be a pain in the whatsit to change.
string body = "Name: " + tbName.Text + "\n" ...;
So I have put the form into an object which has a ton of string properties and two bool (if needed could be changed to string) but I am having an issue putting all of the object's properties into a single string for the email body.
And so on, to
CompanyClass myObj = new CompanyClass();
myObj.Name = tbName.Text;
string body = //where I'm looking to put the object into a function as an argument.
This comes from::
public class CompanyClass
{
public string Name {get;set;}
public string ...
public CompanyClass(string nme, ...)
{
Name = name;
}
public ObjToString(myObj)
{
// where I am having issue
}
}
Is this possible? Speed isn't an issue as it's only one form.
Cheers.
Reflect across the properties of your new class and append the values together.
foreach(var prop in newObj.GetType().GetProperties())
{
string bodyText = += prop.GetValue(newObj, null));
}
Define array of string formats plus textbox objects, do a loop with string.Format( all_obj[i].ToString(), ((TextBox)all_obj[i + 1]).Text ) and collect all lines. Something like:
StringBuilder res = new StringBuilder();
object all_obj[] = new object[] { "Name: {0}", tbName, ... };
for ( int i = 0; i < all_obj.Length; i += 2 )
res.AppendFormat( all_obj[i].ToString(), ((TextBox)all_obj[i + 1]).Text );

c# rewrite url parameter

I have a simple task without a simple solution.
I have a parameter in the browser that needs to be changed or rewritten
for instance www.contoso.com/countries.aspx?country=UK
all I need is to rewrite the parameter without checking the url so it might appear as:
www.contoso.com/countries.aspx?country=France
I have tried something like that but with no joy
string parameter2 = Request.QueryString["country"];
Context.RewritePath(parameter2.Replace("?country=", "France"));
You could do something like this:
var url = "www.contoso.com/countries.aspx?country={0}";
var country = "UK";
url = String.Format(url, country);
Alternatively you can do:
var url = Request.Url.AbsolutePath;
var country = Request.QueryString["country"];
url = url.Replace(country, "UK");
Then:
Response.Redirect(url);
Can you not read the whole URL into a string, split it on the '?' and then add your new bit to the first part of the string?
Something like this:
var url = Request.QueryString;
var newUrl = url.split('?');
url = newUrl[0] + "?country=France";
I dont know if that will work, its just a thought
If you want to replace the complete querystring, use
newVal = string.LastIndexOf("?");
and then
URL.Replace(oldVal, newVal);
OR if you have just one parameter in querystring and want to replace only value of it, use
newVal = string.LastIndexOf("=");
URL.Replace(oldVal, newVal);
Look at this detailed response for solution to your problem.

A clean way of generating QueryString parameters for web requests

I came across a problem in my current application that required fiddling with the query string in a base Page class (which all my pages inherit from) to solve the problem. Since some of my pages use the query string I was wondering if there is any class that provides clean and simple query string manipulation.
Example of code:
// What happens if I want to future manipulate the query string elsewhere
// (e.g. maybe rewrite when the request comes back in)
// Or maybe the URL already has a query string (and the ? is invalid)
Response.Redirect(Request.Path + "?ProductID=" + productId);
Use HttpUtility.ParseQueryString, as someone suggested (and then deleted).
This will work, because the return value from that method is actually an HttpValueCollection, which inherits NameValueCollection (and is internal, you can't reference it directly). You can then set the names/values in the collection normally (including add/remove), and call ToString -- which will produce the finished querystring, because HttpValueCollection overrides ToString to reproduce an actual query string.
I was hoping to find a solution built into the framework but didn't. (those methods that are in the framework require to much work to make it simple and clean)
After trying several alternatives I currently use the following extension method: (post a better solution or comment if you have one)
public static class UriExtensions
{
public static Uri AddQuery(this Uri uri, string name, string value)
{
string newUrl = uri.OriginalString;
if (newUrl.EndsWith("&") || newUrl.EndsWith("?"))
newUrl = string.Format("{0}{1}={2}", newUrl, name, value);
else if (newUrl.Contains("?"))
newUrl = string.Format("{0}&{1}={2}", newUrl, name, value);
else
newUrl = string.Format("{0}?{1}={2}", newUrl, name, value);
return new Uri(newUrl);
}
}
This extension method makes for very clean redirection and uri manipulation:
Response.Redirect(Request.Url.AddQuery("ProductID", productId).ToString());
// Will generate a URL of www.google.com/search?q=asp.net
var url = new Uri("www.google.com/search").AddQuery("q", "asp.net")
and will work for the following Url's:
"http://www.google.com/somepage"
"http://www.google.com/somepage?"
"http://www.google.com/somepage?OldQuery=Data"
"http://www.google.com/somepage?OldQuery=Data&"
Note that whatever route you use, you should really encode the values - Uri.EscapeDataString should do that for you:
string s = string.Format("http://somesite?foo={0}&bar={1}",
Uri.EscapeDataString("&hehe"),
Uri.EscapeDataString("#mwaha"));
What I usually do is just rebuild the querystring. Request has a QueryString collection.
You can iterator over that to get the current (unencoded) parameters out, and just join them together (encoding as you go) with the appropriate separators.
The advantage is that Asp.Net has done the original parsing for you, so you don't need to worry about edge cases such as trailing & and ?s.
I find my way for easy manipulating with get parameters.
public static string UrlFormatParams(this string url, string paramsPattern, params object[] paramsValues)
{
string[] s = url.Split(new string[] {"?"}, StringSplitOptions.RemoveEmptyEntries);
string newQueryString = String.Format(paramsPattern, paramsValues);
List<string> pairs = new List<string>();
NameValueCollection urlQueryCol = null;
NameValueCollection newQueryCol = HttpUtility.ParseQueryString(newQueryString);
if (1 == s.Length)
{
urlQueryCol = new NameValueCollection();
}
else
{
urlQueryCol = HttpUtility.ParseQueryString(s[1]);
}
for (int i = 0; i < newQueryCol.Count; i++)
{
string key = newQueryCol.AllKeys[i];
urlQueryCol[key] = newQueryCol[key];
}
for (int i = 0; i < urlQueryCol.Count; i++)
{
string key = urlQueryCol.AllKeys[i];
string pair = String.Format("{0}={1}", key, urlQueryCol[key]);
pairs.Add(pair);
}
newQueryString = String.Join("&", pairs.ToArray());
return String.Format("{0}?{1}", s[0], newQueryString);
}
Use it like
"~/SearchInHistory.aspx".UrlFormatParams("t={0}&s={1}", searchType, searchString)
Check This!!!
// First Get The Method Used by Request i.e Get/POST from current Context
string method = context.Request.HttpMethod;
// Declare a NameValueCollection Pair to store QueryString parameters from Web Request
NameValueCollection queryStringNameValCollection = new NameValueCollection();
if (method.ToLower().Equals("post")) // Web Request Method is Post
{
string contenttype = context.Request.ContentType;
if (contenttype.ToLower().Equals("application/x-www-form-urlencoded"))
{
int data = context.Request.ContentLength;
byte[] bytData = context.Request.BinaryRead(context.Request.ContentLength);
queryStringNameValCollection = context.Request.Params;
}
}
else // Web Request Method is Get
{
queryStringNameValCollection = context.Request.QueryString;
}
// Now Finally if you want all the KEYS from QueryString in ArrayList
ArrayList arrListKeys = new ArrayList();
for (int index = 0; index < queryStringNameValCollection.Count; index++)
{
string key = queryStringNameValCollection.GetKey(index);
if (!string.IsNullOrEmpty(key))
{
arrListKeys.Add(key.ToLower());
}
}

Categories