I want remove "Language" querystring from my url. How can I do this? (using Asp.net 3.5 , c#)
Default.aspx?Agent=10&Language=2
I want to remove "Language=2", but language would be the first,middle or last. So I will have this
Default.aspx?Agent=20
If it's the HttpRequest.QueryString then you can copy the collection into a writable collection and have your way with it.
NameValueCollection filtered = new NameValueCollection(request.QueryString);
filtered.Remove("Language");
Here is a simple way. Reflector is not needed.
public static string GetQueryStringWithOutParameter(string parameter)
{
var nameValueCollection = System.Web.HttpUtility.ParseQueryString(HttpContext.Current.Request.QueryString.ToString());
nameValueCollection.Remove(parameter);
string url = HttpContext.Current.Request.Path + "?" + nameValueCollection;
return url;
}
Here QueryString.ToString() is required because Request.QueryString collection is read only.
Finally,
hmemcpy answer was totally for me and thanks to other friends who answered.
I grab the HttpValueCollection using Reflector and wrote the following code
var hebe = new HttpValueCollection();
hebe.Add(HttpUtility.ParseQueryString(Request.Url.Query));
if (!string.IsNullOrEmpty(hebe["Language"]))
hebe.Remove("Language");
Response.Redirect(Request.Url.AbsolutePath + "?" + hebe );
My personal preference here is rewriting the query or working with a namevaluecollection at a lower point, but there are times where the business logic makes neither of those very helpful and sometimes reflection really is what you need. In those circumstances you can just turn off the readonly flag for a moment like so:
// reflect to readonly property
PropertyInfo isreadonly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
// make collection editable
isreadonly.SetValue(this.Request.QueryString, false, null);
// remove
this.Request.QueryString.Remove("foo");
// modify
this.Request.QueryString.Set("bar", "123");
// make collection readonly again
isreadonly.SetValue(this.Request.QueryString, true, null);
I answered a similar question a while ago. Basically, the best way would be to use the class HttpValueCollection, which the QueryString property actually is, unfortunately it is internal in the .NET framework.
You could use Reflector to grab it (and place it into your Utils class). This way you could manipulate the query string like a NameValueCollection, but with all the url encoding/decoding issues taken care for you.
HttpValueCollection extends NameValueCollection, and has a constructor that takes an encoded query string (ampersands and question marks included), and it overrides a ToString() method to later rebuild the query string from the underlying collection.
Try this ...
PropertyInfo isreadonly =typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
isreadonly.SetValue(this.Request.QueryString, false, null);
this.Request.QueryString.Remove("foo");
Gather your query string by using HttpContext.Request.QueryString. It defaults as a NameValueCollection type.
Cast it as a string and use System.Web.HttpUtility.ParseQueryString() to parse the query string (which returns a NameValueCollection again).
You can then use the Remove() function to remove the specific parameter (using the key to reference that parameter to remove).
Use case the query parameters back to a string and use string.Join() to format the query string as something readable by your URL as valid query parameters.
See below for a working example, where param_to_remove is the parameter you want to remove.
Let's say your query parameters are param1=1¶m_to_remove=stuff¶m2=2. Run the following lines:
var queryParams = System.Web.HttpUtility.ParseQueryString(HttpContext.Request.QueryString.ToString());
queryParams.Remove("param_to_remove");
string queryString = string.Join("&", queryParams.Cast<string>().Select(e => e + "=" + queryParams[e]));
Now your query string should be param1=1¶m2=2.
You don't make it clear whether you're trying to modify the Querystring in place in the Request object. Since that property is read-only, I guess we'll assume you just want to mess with the string.
... In which case, it's borderline trivial.
grab the querystring off the Request
.split() it on '&'
put it back together into a new string, while sniffing for and tossing out anything starting with "language"
Get the querystring collection, parse it into a (name=value pair) string, excluding the one you want to REMOVE, and name it newQueryString
Then call Response.Redirect(known_path?newqueryString);
You're probably going to want use a Regular Expression to find the parameter you want to remove from the querystring, then remove it and redirect the browser to the same file with your new querystring.
Yes, there are no classes built into .NET to edit query strings. You'll have to either use Regex or some other method of altering the string itself.
If you have already the Query String as a string, you can also use simple string manipulation:
int pos = queryString.ToLower().IndexOf("parameter=");
if (pos >= 0)
{
int pos_end = queryString.IndexOf("&", pos);
if (pos_end >= 0) // there are additional parameters after this one
queryString = queryString.Substring(0, pos) + queryString.Substring(pos_end + 1);
else
if (pos == 0) // this one is the only parameter
queryString = "";
else // this one is the last parameter
queryString=queryString.Substring(0, pos - 1);
}
well I have a simple solution , but there is a little javascript involve.
assuming the Query String is "ok=1"
string url = Request.Url.AbsoluteUri.Replace("&ok=1", "");
url = Request.Url.AbsoluteUri.Replace("?ok=1", "");
Response.Write("<script>window.location = '"+url+"';</script>");
string queryString = "Default.aspx?Agent=10&Language=2"; //Request.QueryString.ToString();
string parameterToRemove="Language"; //parameter which we want to remove
string regex=string.Format("(&{0}=[^&\s]+|{0}=[^&\s]+&?)",parameterToRemove);
string finalQS = Regex.Replace(queryString, regex, "");
https://regexr.com/3i9vj
Parse Querystring into a NameValueCollection. Remove an item. And use the toString to convert it back to a querystring.
using System.Collections.Specialized;
NameValueCollection filteredQueryString = System.Web.HttpUtility.ParseQueryString(Request.QueryString.ToString());
filteredQueryString.Remove("appKey");
var queryString = '?'+ filteredQueryString.ToString();
ASP .NET Core (native, don't have to reference any additional libraries)
Within an ASP .NET Core Controller you would have access to an instance of Request
Request.Query is a query collection representing the query parameters, cast it to a list
From which you can filter and remove the params you want
Use QueryString.Create, which can take the list you just filtered as an input & generate a query string directly
var removeTheseParams = new List<string> {"removeMe1", "removeMe2"}.AsReadOnly();
var filteredQueryParams = Request.Query.ToList().Where(filterKvp => !removeTheseParams.Contains(filterKvp.Key));
var filteredQueryString = QueryString.Create(queryParamsFilteredList).ToString();
//Example: Console.Writeline(filteredQueryString) will give you "?q1=v1&q2=v2"
Optional Part Below: Can also encode those values if they are unsafe,
so in addition to the Where() above UrlEncode the query parameter keys and values using a Select() as shown below:
//Optional
.Select(cleanKvp => new KeyValuePair<string, string?>(UrlEncoder.Default.Encode(cleanKvp.Key),UrlEncoder.Default.Encode(cleanKvp.Value)))
Related
I have been following this link: Build query string for System.Net.HttpClient get
but my situation was a little different and was not sure what the best approach would be. As of now I am thinking about going with a for loop but figured there might be a better approach.I have a list of parameters. I thought about just for looping over the list but that would make it where the querystring would be "?foo=1?foo=2"
See below example as to what I am looking for and what I have so far
var query = HttpUtility.ParseQueryString(string.Empty);
List<String> foos = ...
query["foo"] = "1";
string queryString = query.ToString()
//Expected query string to be ?foo=1&foo=2
Try Add method on NameViewCollection
With Add method you can add multiple values for a single key.
var qs = HttpUtility.ParseQueryString(string.Empty);
qs.Add("foo", "1");
qs.Add("foo", "2");
qs.ToString(); would give you foo=1&foo=2
I am trying to use the Classic ASP Intrinsic objects in C#. Through using the ASPTypeLibrary.
I would like to convert the Classic ASP Request object Request.QueryString and Request.Form into NameValueCollections.
How can I do this?
I would like to convert the Request.QueryString and Request.Form objects into NameValueCollections. How can I do this?
The return type of them both is NameValueCollection:
public NameValueCollection QueryString { get; }
public NameValueCollection Form { get; }
You can simply foreach them, for example:
PrintKeysAndValues(Request.Form);
PrintKeysAndValues(Request.Request);
public static void PrintKeysAndValues( NameValueCollection myCol ) {
Console.WriteLine( " KEY VALUE" );
foreach ( String s in myCol.AllKeys )
Console.WriteLine( " {0,-10} {1}", s, myCol[s] );
Console.WriteLine();
}
So you don't need to convert them.
What do you mean "convert"? Both those properties are NameValueCollections:
HttpRequest.Form is a NameValueCollection of form variables. If the page was posted using the HTTP verb POST, the data comes from the request body; if the page was posted using the HTTP verb GET, the data comes from the query string.
HttpRequest.QueryString is a NameValueCollection of key/value pairs taken from the...wait for it...query string of the form ...?key1=value1&key1=value1&.... Any repeated keys will result in the values being concatated into a single string with each individual value separated by commas: ...?foo=1&foo=2&foo=3 will result in the key foo having the value 1,2,3.
One should note, though, with respect to the query string that the HTTP protocol does not place any particular strictures on query string syntax: everything in a URI following the ? (and up to the first # indicating the beginning of the fragment, or the end of the URI, whichever comes first) is the query: its interpretation is completely up to the authority whose URI it is. Sadly, Microsoft's HttpRequest class makes the decision for you.
Old post, but maybe someone still need an answer to this and how to access different content from the ScriptingContext. It tooks me almost a year to find out how this works ...
This code works for me to get the QueryString. In the example I build it again to a complete string:
foreach (var item in _scriptContext.Request.QueryString)
{
foreach (var q in _scriptContext.Request.QueryString[item])
qs += item + "=" + q + "&";
}
if (qs.EndsWith("&")) qs = qs.Substring(0, qs.Length - 1);
In this context getting ServerVariables:
var uri = "";
foreach (var item in _scriptContext.Request.ServerVariables["URL"])
uri = item.ToString();
Application and Session return the content direct:
var app_var = _scriptContext.Application["application_var"]
var sess_var = _scriptContext.Session["session_var"]
Reading a cookie works like this:
dynamic value = (IReadCookie)_scriptContext.Request.Cookies["cookieName"];
var yourCookie = value.Item().ToString();
In MVC 2 I have a RedirectToAction call which I need to pass all of the querystring parameters. Unfortunately I can only find a way to pass named querystring parameters is there a way of passing all querystring parameters regardless.
We have one named parameter, id but we just want to append all of the rest onto the end of the URL without setting them explicitly.
return RedirectToAction("index", "enquiry", new { id = enquiryCacheId.ToString()});
You cannot pass COMPLEX objects in URLs, so that kills the option of passing on Complex types in new { }.
One option what you are left with is to encode the querystring and then send that in 'id'. Say for examples, you have querystring as follows name=rami&gender=male. Then you can encode it with HttpUtility.UrlEncode(), then set it to id=[encoded string]. On the other action (retrieving side) you can get id value and then use HttpUtility.UrlDecode() to decode the string. Then finally you can use HttpUtility.ParseQueryString() to split the querystring into NameValueCollection.
If above suggestion is not what you are looking for then. you need to add all querystring parameters to new { } in the RedirectToAction(). If you want to customize it then you might need to go to ASP.Net MVC Source code #CodePlex and make your own builds (which I think not worthy for this kind of requirement).
I have an extension method that I use to modify the querystring of the current URL:
public static string ModifyQueryString(this UrlHelper helper, NameValueCollection updates, IEnumerable<string> removes)
{
var request = helper.RequestContext.HttpContext.Request;
var url = request.Url.AbsolutePath;
var query = HttpUtility.ParseQueryString(request.QueryString.ToString());
updates = updates ?? new NameValueCollection();
foreach (string key in updates.Keys)
{
query.Set(key, updates[key]);
}
removes = removes ?? new List<string>();
foreach (string param in removes)
{
query.Remove(param);
}
if (query.HasKeys())
{
return string.Format("{0}?{1}", url, query.ToString());
}
else
{
return url;
}
}
But, if you need to modify an arbitrary URL, it should be easy enough to modify. You would just need to add a parameter to accept an arbitrary URL, and then instead of getting the URL/querystring from the HttpContext, you just split the passed URL at ?. The rest of the code should work the same.
Is there a class in the .NET framework which, if given a sequence/enumerable of key value pairs (or anything else I am not rigid on the format of this) can create a query string like this:
?foo=bar&gar=har&print=1
I could do this trivial task myself but I thought I'd ask to save myself from re-inventing the wheel. Why do all those string gymnastics when a single line of code can do it?
You can use System.Web.HttpUtility.ParseQueryString to create an empty System.Web.HttpValueCollection, and use it like a NameValueCollection.
Example:
var query = System.Web.HttpUtility.ParseQueryString(string.Empty);
query ["foo"] = "bar";
query ["gar"] = "har";
query ["print"] = "1";
var queryString = query.ToString(); // queryString is 'foo=bar&gar=har&print=1'
There's nothing built in to the .NET framework, as far as I know, though there are a lot of almosts.
System.Web.HttpRequest.QueryString is a pre-parsed NameValueCollection, not something that can output a querystring. System.NetHttpWebRequest expects you to pass a pre-formed URI, and System.UriBuilder has a Query property, but again, expects a pre-formed string for the entire query string.
However, running a quick search for "querystringbuilder" shows a couple of implementations for this out in the web that could serve. One such is this one by Brad Vincent, which gives you a simple fluent interface:
//take an existing string and replace the 'id' value if it exists (which it does)
//output : "?id=5678&user=tony"
strQuery = new QueryString("id=1234&user=tony").Add("id", "5678", true).ToString();
And, though not exactly very elegant, I found a method in RestSharp, as suggested by #sasfrog in the comment to my question. Here's the method.
From RestSharp-master\RestSharp\Http.cs
private string EncodeParameters()
{
var querystring = new StringBuilder();
foreach (var p in Parameters)
{
if (querystring.Length > 0)
querystring.Append("&");
querystring.AppendFormat("{0}={1}", p.Name.UrlEncode(), p.Value.UrlEncode());
}
return querystring.ToString();
}
And again, not very elegant and not really what I would have been expecting, but hey, it gets the job done and saves me some typing.
I was really looking for something like Xi Huan's answer (marked the correct answer) but this works as well.
There's nothing built into the .NET Framework that preserves the order of the query parameters, AFAIK. The following helper does that, skips null values, and converts values to invariant strings. When combined with a KeyValueList, it makes building URIs pretty easy.
public static string ToUrlQuery(IEnumerable<KeyValuePair<string, object>> pairs)
{
var q = new StringBuilder();
foreach (var pair in pairs)
if (pair.Value != null) {
if (q.Length > 0) q.Append('&');
q.Append(pair.Key).Append('=').Append(WebUtility.UrlEncode(Convert.ToString(pair.Value, CultureInfo.InvariantCulture)));
}
return q.ToString();
}
Using the following code I get a nice formatted string:
Request.QueryString.ToString
Gives me something like: &hello=worldµsoft=sucks
But when I use this code to clone the collection to another object (of the same type) I get the Type() back from the ToString() method instead.
System.Collections.Specialized.NameValueCollection variables = new System.Collections.Specialized.NameValueCollection(Request.QueryString);
if (!string.IsNullOrEmpty(variables["sid"]))
variables.Remove("sid");
Response.Write(variables.ToString());
Is there a tidier way to output it rather than looking and building the string manually?
HttpValueCollection is internal, but you can use "var" to declare it without extract it with reflector.
var query = HttpUtility.ParseQueryString(Request.Url.Query);
query["Lang"] = myLanguage; // Add or replace param
string myNewUrl = Request.Url.AbsolutePath + "?" + query;
You can also use Reflector to extract the HttpValueCollection class into your own, and use it then.
Because it is actually a special NVC that is of type HTTPValueCollection.
So when you call .ToString on it, it knows how to format it correctly.
Why do you want to copy the QueryString collection into a new NameValueCollection?
if (!string.IsNullOrEmpty(Request.QueryString["sid"]))
Request.QueryString.Remove("sid");
Yes indeed, i am wrong, it is read only. So the essence is to use the Remove Method on your NameValuecollection:
System.Collections.Specialized.NameValueCollection variables = new System.Collections.Specialized.NameValueCollection(Request.QueryString);
if (!string.IsNullOrEmpty(variables["sid"]))
variables.Remove("sid");
If you don't absolutely need a NameValueCollection, A dictionary offers a lot of the same semantics:
var variables = Request.QueryString.OfType<DictionaryEntry>()
.Where(entry => entry.Key != "sid")
.ToDictionary(entry => entry.Key, entry => entry.Value);
Request.QueryString actually return a HttpValueCollection object (which unfortuately, is internal to System.Web so you can't you it).
Nevertheless, HttpValueCollection is derived from NameValueCollection, and it's Remove() method remains intact, so you should be able to call Request.QueryString.Remove("sid");