问题
I have an HttpContext.Request object that has data in the Form that is wrong and I want to fix it up and send the correct HttpContext on its way. HttpContext.Request.Form is readonly, but if it wasn't I would have simply done the following; HttpContext.Request.Form["a"] = "the correct value for a";
So, where is the best place in the pipeline to do this. Is it possible to make the HttpContext.Request.Form write accessable via reflection?
回答1:
This was easier than I thought. I am doing this in my middleware which is there to correct bad form data that came in.
public async Task Invoke(HttpContext context)
{
....
NameValueCollection fcnvc = context.Request.Form.AsNameValueCollection();
fcnvc.Set("a", "the correct value of a");
fcnvc.Set("b", "a value the client forgot to post");
Dictionary<string, StringValues> dictValues = new Dictionary<string, StringValues>();
foreach (var key in fcnvc.AllKeys)
{
dictValues.Add(key, fcnvc.Get(key));
}
var fc = new FormCollection(dictValues);
context.Request.Form = fc;
....
await _next.Invoke(context);
}
Interestingly the FormCollection is readonly, but the HttpContext.Request object is not thus allowing me to replace the entire Form.
回答2:
AsNameValueCollection is inside of IdentityServer4.dll.
public static class IReadableStringCollectionExtensions
{
[DebuggerStepThrough]
public static NameValueCollection AsNameValueCollection(this IDictionary<string, StringValues> collection)
{
NameValueCollection values = new NameValueCollection();
foreach (KeyValuePair<string, StringValues> pair in collection)
{
string introduced3 = pair.get_Key();
values.Add(introduced3, Enumerable.First<string>(pair.get_Value()));
}
return values;
}
[DebuggerStepThrough]
public static NameValueCollection AsNameValueCollection(this IEnumerable<KeyValuePair<string, StringValues>> collection)
{
NameValueCollection values = new NameValueCollection();
foreach (KeyValuePair<string, StringValues> pair in collection)
{
string introduced3 = pair.get_Key();
values.Add(introduced3, Enumerable.First<string>(pair.get_Value()));
}
return values;
}
}
回答3:
A bit complex but shorter solution
var collection = HttpContext.Request.Form;
var propInfo = collection.GetType().GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
propInfo.SetValue(collection, false, new object[]{});
collection.Remove("a");
collection.Add("a", "the correct value for a");
System.Diagnostics.Debug.Write(HttpContext.Request["a"]); // the correct value for a
Enjoy!
来源:https://stackoverflow.com/questions/42701311/how-to-modify-httpcontext-request-form-in-asp-net-core