views:

1852

answers:

2

i try Request.Form.Set(k, v) but it's throw exception Collection is read-only

+1  A: 

The form is a representation of what the client sent in the request. What is it you want to do? Personally, I would try to separate the "read the form" code from the "do something with the values" code - that way, you can do any pre-processing early on (when reading from the form), and none of the later code needs to know about what was actually sent - it just takes the values given to it (i.e. it never talks to the request directly).

If also means you can test your logic without the need for a form, or even an http-request at all.

Actually, ASP.NET MVC will do a lot of this (the above paragraph) for you...

Note that you can update the .Items collection - but this is a bit more vague (i.e. it doesn't relate specifically to the form).

(cheers for fixing the typo btw)

Marc Gravell
+4  A: 

This is exactly the same as modifying Request.Querystring. Both are internally complicated by private properties and what could be deemed a bug, however there are two possible solutions I'm aware of (I'll dismiss the response.redirect plan out of hand - that's terrible).

Method one is to use reflection to modify the collection directly:

NameValueCollection oQuery = Request.QueryString;
oQuery = (NameValueCollection)Request.GetType().GetField("_queryString",BindingFlags.NonPublic | BindingFlags.Instance).GetValue(Request);
PropertyInfo oReadable = oQuery .GetType().GetProperty("IsReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
oReadable.SetValue(oQuery, false, null);
oQuery["foo"] = "bar";
oReadable.SetValue(oQuery, true, null);

Plan B, which I think lends itself better to unit testing is to avoid dealing with the collection directly and instead pass it as a NameValueCollection to any method you want to handle it, shallow copying whatever you need out of it. I've used this myself to mock web requests.

Edit: Marc Gravell gave more eloquent reasons for plan B

annakata
Manipulating private stuff in this manner is by no means a suggested thing and should be avoided as much as possible (~= at all costs). After all they are made private for a reason. You'll rely on a specific version of a library. Any change in the underlying implementation might break your app.
Mehrdad Afshari
And you'll see I advocate plan B
annakata