13

我尝试Request.Form.Set(k, v)但它抛出异常

集合是只读的

4

2 回答 2

13

这与修改Request.Querystring. 两者在内部都因私有属性而变得复杂,并且可能被视为错误,但是我知道有两种可能的解决方案(我会立即取消 response.redirect 计划 - 这太糟糕了)。

方法一是使用反射直接修改集合:

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

我认为更适合单元测试的计划 B 是避免直接处理集合,而是将其作为 a 传递NameValueCollection给您想要处理它的任何方法,浅拷贝您需要的任何内容。我自己用它来模拟网络请求。

编辑:Marc Gravell 为 B 计划给出了更有说服力的理由

于 2008-11-27T09:27:54.650 回答
1

表单表示客户端在请求中发送的内容。你想做什么?就个人而言,我会尝试将“读取表单”代码与“使用值做某事”代码分开 - 这样,您可以在早期(从表单读取时)进行任何预处理,而不是稍后代码需要知道实际发送了什么——它只接受给它的值(即它从不直接与请求对话)。

这也意味着您可以测试您的逻辑,而无需表单,甚至根本不需要 http 请求。

实际上,ASP.NET MVC 会为你做很多这样的事情(上一段)......

请注意,您可以更新 .Items 集合 - 但这有点模糊(即它与表单没有具体关系)。

于 2008-11-27T09:15:56.327 回答