【问题标题】:How to modify HttpContext.Request.Form in asp.net core如何在 asp.net core 中修改 HttpContext.Request.Form
【发布时间】:2017-03-09 17:04:40
【问题描述】:

我有一个 HttpContext.Request 对象,它的表单中有错误的数据,我想修复它并在途中发送正确的 HttpContext。 HttpContext.Request.Form 是只读的,但如果不是,我会简单地执行以下操作; HttpContext.Request.Form["a"] = "a 的正确值";

那么,在管道中执行此操作的最佳位置在哪里。 是否可以通过反射使 HttpContext.Request.Form 可写访问?

【问题讨论】:

  • “在途中发送正确的 HttpContext”到底是什么意思?您是将其传递给另一个方法/对象还是尝试将其发送回客户端?
  • 我正在拦截传入的请求并修复中间件中的错误表单数据,并将好的表单数据发送到传入管道的其余部分。

标签: c# asp.net-core httpcontext


【解决方案1】:

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

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 是只读的,但 HttpContext.Request 对象不允许我替换整个表单。

【讨论】:

  • 我没有AsNameValueCollection扩展方法!它在哪里?
  • AsNameValueCollection 在 IdentityServer4.dll 里面,我把源代码贴在下面。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    有点复杂但更短的解决方案

    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
    

    享受吧!

    【讨论】:

      【解决方案4】:

      这是一个 .NET Core/5 解决方案,无需使用 Identity Server 包即可为我工作。

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

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

      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;
      

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

      var formDictionary = new Dictionary<string, StringValues>();
      var form = context.Request.Form;
      
      foreach (var key in form.Keys)
      {
          form.TryGetValue(key, out StringValues formValues);
      
          // Change client_id value to "NewValue"
          if (key == "client_id")
          {
              formValues = new string[] { "NewValue" };
          }
      
          formDictionary.Add(key, formValues);
      }
      
      FormCollection formCollection = new FormCollection(formDictionary);
      
      context.Request.Form = formCollection;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-03
        • 1970-01-01
        相关资源
        最近更新 更多