54

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
peterh
  • 11,875
  • 18
  • 85
  • 108
Barbaros Alp
  • 6,405
  • 8
  • 47
  • 61
  • Please, explain more of what your purpose are. I do not think you are looking for a way to edit the users address field, are you? – Martin Bring Feb 09 '09 at 19:56

16 Answers16

116

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");
xcud
  • 14,422
  • 3
  • 33
  • 29
  • 2
    this is both simple and elegant - wish i could bump a couple of times – Doug Feb 07 '11 at 06:33
  • 5
    Thanks for that Doug. I'm a bit baffled by the accepted answer. It sounds like questioner is causing another navigation to occur to get the unwanted parameter out of the querystring. – xcud Feb 07 '11 at 20:24
  • System.Collections.Specialized.NameValueCollection filtered = new System.Collections.Specialized.NameValueCollection(Request.QueryString); – live-love Mar 17 '16 at 17:16
46

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.

Paulius Zaliaduonis
  • 5,059
  • 3
  • 28
  • 23
  • 2
    Simplest, most elegant solution. – Blairg23 Feb 29 '16 at 23:13
  • One note here is that the line `string url = HttpContext.Current.Request.Path + "?" + nameValueCollection;` will encode the `nameValueCollection`, so sometimes spaces become "+", which might not be the right syntax for the request you are about to make. In my case, it wasn't. I had to map the keys and values in a for loop instead. – Blairg23 Mar 13 '16 at 06:15
36

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 );
Barbaros Alp
  • 6,405
  • 8
  • 47
  • 61
  • 2
    This is the correct answer here. The .NET framework has the HTTP utility parse query string method for exactly this purpose. There is no need to duplicate code from a reflector or use regular expressions. The reason that the query string collection in the request context is read-only is because modifying it would make the context in-accurate from the original request. The parse query string method simply gives you a brand new collection not tied to the request context which is not read-only. Please could you mark this as the correct answer here, thanks. – Daniel Bradley Apr 11 '11 at 11:04
  • I prefer to do this without the redirect if it is possible, which it is using Reflection (see @annakata's answer) – LocalPCGuy Mar 16 '12 at 18:44
  • It looks like ParseQueryString returns a read/write HttpValueCollection, so there's no need to create your own version of it. See Paulius Zaliaduonis answer below. – Tom Winter Jan 16 '13 at 23:24
  • There is a reason to why that class is internal, you know. This solution might not work on future .net versions – Radu Simionescu Feb 07 '14 at 08:53
  • This does not work for me using .net 4.5 and ASP.NET MVC 5. Creating new HttpValueCollection objects is not possible due to the security level. – Krisztián Balla Jul 24 '14 at 09:24
26

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);
annakata
  • 74,572
  • 17
  • 113
  • 180
  • Great stuff. Is this not dangerous at all? What is the scope of this.Request.QueryString in this context? – Skuli Feb 10 '11 at 18:46
  • @Skuli - You're modifying something which isn't intended for modification, and you're doing that by changing a state flag. There's some risk that you might do something destructive if you forget to "close" the reflection change, but it's pretty low and would require a developer to be pretty unaware of what the code is doing. Request here is scoped through IHttpHandler, so any old System.Web.Page can do this. – annakata Feb 11 '11 at 08:33
  • 1
    I am using this in a case where I have a UserControl I can't modify that uses a query string parameter, and the only way to change the way that UserControl behaves is to change the query string before it processes it (I also can't change the actual incoming URL, I have to modify it during the the load cycle.) Very helpful, and it works great. – LocalPCGuy Mar 16 '12 at 18:48
  • This gave me a System.NotSupportedException: Collection is read-only. on Request.QueryString.Remove – Mark Rogers Jul 11 '13 at 06:03
10

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.

Community
  • 1
  • 1
Igal Tabachnik
  • 31,174
  • 15
  • 92
  • 157
  • I have read your post, and it sounds great. Thanks for your answer, i ll try it and get back – Barbaros Alp Feb 09 '09 at 20:28
  • Not sure if this was the only method available in 2009 but there's another way without reflection in another answer for this question: http://stackoverflow.com/a/7530346/169034 – Fabio Milheiro Sep 11 '14 at 10:59
3

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");
Vishal Nayan
  • 65
  • 1
  • 8
2
  1. Gather your query string by using HttpContext.Request.QueryString. It defaults as a NameValueCollection type.
  2. Cast it as a string and use System.Web.HttpUtility.ParseQueryString() to parse the query string (which returns a NameValueCollection again).
  3. You can then use the Remove() function to remove the specific parameter (using the key to reference that parameter to remove).
  4. 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&param_to_remove=stuff&param2=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&param2=2.

Blairg23
  • 11,334
  • 6
  • 72
  • 72
1

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"
Jason Kester
  • 5,951
  • 9
  • 35
  • 40
  • Agreed, if you don't want to mess with RegEx's, get the Query from Rquest.Url.Query, split on &, and rebuild it without the language querystring. You can use a UriBuilder, but it doesn't take name value pairs to build querystrings :( – Zhaph - Ben Duguid Feb 09 '09 at 20:16
  • I long ago built my own LinkUri class that can tear apart urls, build them off of key/value, and .tostring() them into URLs again. Basically, it does what you wish UriBuilder did. Took a morning to put together 4 years ago, and I use it every single day. – Jason Kester Feb 09 '09 at 20:26
  • I am on it know, i hate playing with strings, ohh god :) But with this way i feel most comfortable – Barbaros Alp Feb 09 '09 at 20:27
  • ... so this example would be: return (new LinkUri(Request.Url)).Remove("language").ToString(); – Jason Kester Feb 09 '09 at 20:27
1

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

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Pita.O
  • 1,864
  • 1
  • 19
  • 27
0

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

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>");
Segev Dagan
  • 119
  • 2
  • 11
  • 2
    this would probably be the absolule worst way of doing it – Jason Loki Smith May 27 '15 at 11:16
  • please explain what is the problem ,insted write your opinion without explanation – Segev Dagan May 27 '15 at 13:58
  • 1
    The value "1" in your example will most likely be dynamic, which means that the string "&ok=1" or "?ok=1" will have to be manually built up and then replaced. Your answer is not the cleanest way of doing what is asked. Also, the question that was asked had no javascript implementation mentioned. – Jason Loki Smith May 28 '15 at 07:06
  • 1
    so use "&ok="+lanID.Tostring() ,and it is very common to use java script in asp.net , i agree that there is other cleanest why to implement , but it is a answer and it's work! – Segev Dagan May 28 '15 at 15:16
0
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

yajiv
  • 2,901
  • 2
  • 15
  • 25
0

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.

RKitson
  • 2,003
  • 1
  • 18
  • 21
0

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.

David Morton
  • 16,338
  • 3
  • 63
  • 73
0

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();
vijayst
  • 20,359
  • 18
  • 69
  • 113
Kurkula
  • 6,386
  • 27
  • 127
  • 202
0

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)))
Sunny
  • 119
  • 1
  • 2
  • 13