How to modify HttpContext.Request.Form in asp.net core

僤鯓⒐⒋嵵緔 提交于 2019-12-10 16:24:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!