我有一个HttpContext.Request对象,其中Form中的数据是错误的,我想修复它并在其路上发送正确的HttpContext。 HttpContext.Request.Form是readonly,但如果不是,我会简单地完成以下操作; HttpContext.Request.Form [“a”] =“正确的值”;
那么,管道中最好的地方就是这样做的。 是否可以通过反射使HttpContext.Request.Form写入可访问?
答案 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;