Question

In my base page I need to remove an item from the query string and redirect. I can't use

Request.QueryString.Remove("foo")

because the collection is read-only. Is there any way to get the query string (except for that one item) without iterating through the collection and re-building it?

Was it helpful?

Solution

You'd have to reconstruct the url and then redirect. Something like this:

string url = Request.RawUrl;

NameValueCollection params = Request.QueryString;
for (int i=0; i<params.Count; i++)
{
    if (params[i].GetKey(i).ToLower() == "foo")
    {
        url += string.Concat((i==0 ? "?" : "&"), params[i].GetKey(i), "=", params.Get(i));
    }
}
Response.Redirect(url);

Anyway, I didn't test that or anything, but it should work (or at least get you in thye right direction)

OTHER TIPS

You can avoid touching the original query string by working on a copy of it instead. You can then redirect the page to the a url containing your modified query string like so:

    var nvc = new NameValueCollection();

    nvc.Add(HttpUtility.ParseQueryString(Request.Url.Query));

    nvc.Remove("foo");

    string url = Request.Url.AbsolutePath;

    for (int i = 0; i < nvc.Count; i++)
        url += string.Format("{0}{1}={2}", (i == 0 ? "?" : "&"), nvc.Keys[i], nvc[i]);

    Response.Redirect(url);

Update:

Turns out we can simplify the code like so:

    var nvc = HttpUtility.ParseQueryString(Request.Url.Query);

    nvc.Remove("foo");

    string url = Request.Url.AbsolutePath + "?" + nvc.ToString();

    Response.Redirect(url);
Response.Redirect(String.Format("nextpage.aspx?{0}", Request.QueryString.ToString().Replace("foo", "mangledfoo")));

I quick hack, saves you little. But foo will not be present for the code awaiting it in nextpge.aspx :)

Interesting question. I don't see any real viable alternative to manually copying the collection since CopyTo will only allow you to get the values (and not the keys).

I think HollyStyles' Hack would work (although I would be nervous about putting a Replace in a QueryString - obv. dependant on use case), but there is one thing thats bothering me..

If the target page is not reading it, why do you need to remove it from the QueryString?

It will just be ignored?

Failing that, I think you would just need to bite the bullet and create a util method to alter the collection for you.

UPDATE - Following Response from OP

Ahhhh! I see now, yes, I have had similar problems with SiteMap performing full comparison of the string.

Since changing the other source code (i.e. the search) is out of the question, I would probably say it may be best to do a Replace on the string. Although to be fair, if you often encounter code similar to this, it would equally be just as quick to set up a utility function to clone the collection, taking an array of values to filter from it.

This way you would never have to worry about such issues again :)

HttpUtility.ParseQueryString(Request.Url.Query) return isQueryStringValueCollection. It is inherit 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); 

The search page appends "&terms=" to the query string for highlighting, so it messes it up.

Only other option is a regex replace. If you know for sure that &terms is in the middle of the collection somewhere leave the trailing & in the regex, if you know for sure it's on the end then drop the trailing & and change the replacement string "&" to String.Empty

Response.Redirect(String.Format("nextpage.aspx?{0}", Regex.Replace(Request.QueryString.ToString(), "&terms=.*&", "&"));

Request.Url.GetLeftPart(UriPartial.Path) should do this

I found this was a more elegant solution

var qs = HttpUtility.ParseQueryString(Request.QueryString.ToString());
qs.Remove("item");
Console.WriteLine(qs.ToString());

Here is a solution that uses LINQ against the Request.QueryString which allows for complex filtering of qs params if required.

The example below shows me filtering out the uid param to create a relative url ready for redirection.

Before: http://www.domain.com/home.aspx?color=red&uid=1&name=bob

After: ~/home.aspx?color=red&name=bob

Remove QS param from url

var rq = this.Request.QueryString;
var qs = string.Join("&", rq.Cast<string>().Where(k => k != "uid").Select(k => string.Format("{0}={1}", k, rq[k])).ToArray());
var url = string.Concat("~", Request.RawUrl.Split('?')[0], "?", qs);

Can you clone the collection and then redirect to the page with the cloned (and modified) collection?

I know it's not much better than iterating...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top