23

Using the following code I get a nice formatted string:

Request.QueryString.ToString 

Gives me something like: &hello=world&microsoft=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?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Anthony Main
  • 6,039
  • 12
  • 64
  • 89

6 Answers6

69

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;
Michele Bersini
  • 698
  • 5
  • 4
  • 2
    Nice idea! But `var` isn't doing anything for you here, that's just virtual method dispatch. `NameValueCollection values = HttpUtility.ParseQueryString(...)` will work just as well. Also I'd add a comment to explain what you're doing. – Ben Challenor Jan 05 '12 at 12:22
  • Also `HttpUtility.ParseQueryString("")` works nicely if you want an empty one. – Ben Challenor Jan 05 '12 at 12:24
  • +1. ¿But why not `NameValueCollection` instead of `var`? BTW, it works for me. – Dani Rodríguez Jul 11 '12 at 07:35
  • We can use either `Request.Url.Query` or `Request.QueryString.ToString()`. I guess `Request.Url.Query` has a better performance. The only difference between these two is `Request.Url.Query` return a question mark `?` in front, but fortunately `HttpUtility.ParseQueryString()` doesn't care. – Jaider Jul 18 '12 at 23:13
  • This answer should really just say 'to get a mutable query string object (NameValueCollection) you can use `HttpUtility.ParseQueryString`', no? – mcNux Jul 29 '14 at 14:12
  • Just cut about 12 lines of code thanks to this. Combine it with Uri.GetLeftPart and you're golden. var query = HttpUtility.ParseQueryString(request.Url.Query); query.Remove("code"); var myNewUrl = request.Url.GetLeftPart(UriPartial.Path) + "?" + query; – kingdango Oct 14 '14 at 14:12
  • var keyword in C# is syntactic sugar. NameValueCollection values = ... and var values = ... produces the exact same and identical IL. var says to the compiler "the left part of the assignment is of the same type as the right part". – Thanasis Ioannidis Sep 22 '15 at 14:03
8

You can also use Reflector to extract the HttpValueCollection class into your own, and use it then.

Irvin Dominin
  • 30,819
  • 9
  • 77
  • 111
Igal Tabachnik
  • 31,174
  • 15
  • 92
  • 157
  • I'm giving you the win here hmemcpy as its probably the most appropriate but it doesnt solve my problem, guess I'll just have to do it the dirty way – Anthony Main Oct 23 '08 at 14:44
  • Actually, you pretty much just need the HttpValueCollection.ToString(bool urlencoded, IDictionary excludeKeys) method. – James Curran Oct 23 '08 at 14:44
  • Yup, just like James said, the HttpValueCollection overrides ToString() to create the query string with HttpEncoded values and ampersands. You can use Add/Remove on the values, and later call ToString() to create your new query string. – Igal Tabachnik Oct 23 '08 at 15:19
  • Can you tell me about Reflector ? is it the software which you can see the assemblies or something different? – Barbaros Alp Feb 09 '09 at 20:40
  • 1
    Yes Reflector lets you open .net Dll's/Exes and will do test to reproduce the code in it, there are plugins which will allow you to do other things like disassemble to a project – Anthony Main Feb 10 '09 at 09:20
4

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.

Brian Schmitt
  • 6,008
  • 1
  • 24
  • 36
2

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");
Johannes Hädrich
  • 1,223
  • 1
  • 12
  • 20
1

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);
Jimmy
  • 89,068
  • 17
  • 119
  • 137
0

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

James Curran
  • 101,701
  • 37
  • 181
  • 258