如何修改asp.net核心中的HttpContext.Request.Form

时间:2017-03-09 17:04:41

标签: asp.net-core httpcontext

我有一个HttpContext.Request对象,其中Form中的数据是错误的,我想修复它并在其路上发送正确的HttpContext。 HttpContext.Request.Form是readonly,但如果不是,我会简单地完成以下操作; HttpContext.Request.Form [“a”] =“正确的值”;

那么,管道中最好的地方就是这样做的。 是否可以通过反射使HttpContext.Request.Form写入可访问?

4 个答案:

答案 0 :(得分:5)

这比我想象的要容易。我在我的中间件中执行此操作,该中间件用于纠正输入的错误表单数据。

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

有趣的是FormCollection是readonly,但是HttpContext.Request对象因此不允许我替换整个Form。

答案 1 :(得分:1)

AsNameValueCollection位于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;
    }
}

答案 2 :(得分:0)

  

复杂但解决方案较短

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
  

享受!

答案 3 :(得分:0)

这是一个适用于我的 .NET Core/5 解决方案,无需使用 Identity Server 包。

基本上,您从现有的表单集合中构建一个 <string, StringValues> 类型的新字典,根据需要修改字典中的值,然后从该字典创建一个新的 FormCollection 并将其设置为 { {1}}。需要记住的重要一点是,StringValues 类型的值只是一个字符串数组!

此示例演示我从请求表单中删除“client_id”字段。

context.Request.Form

这是我将“client_id”字段更改为“NewValue”的另一个示例

var formDictionary = new Dictionary<string, StringValues>();
var form = context.Request.Form;

foreach (var key in form.Keys)
{
    // Only add if key is NOT client_id
    if (key != "client_id")
    {
        form.TryGetValue(key, out StringValues formValues);

        formDictionary.Add(key, formValues);
    }
}

FormCollection formCollection = new FormCollection(formDictionary);

context.Request.Form = formCollection;