如何修改 asp.net 核心中中间件的表单和查询字符串值?
How to modify form & querystring values at middleware in asp.net core?
我已经创建了一个中间件 class。这个 class 的目的是对所有表单和查询字符串值进行一些更改,但是有一个问题!表单和查询字符串值是只读的,我无法更改它们。怎么办?
public class TestMiddleware
{
private readonly RequestDelegate _next;
public TestMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var collection = httpContext.Request.Query;
foreach (var item in collection)
{
collection[item.Key] = item.Value.ToString().Replace('x', 'y');
}
httpContext.Request.Query = collection;
var collection2 = httpContext.Request.Form;
foreach (var item in collection2)
{
collection2[item.Key] = item.Value.ToString().Replace('x', 'y');
}
httpContext.Request.Form = collection2;
await _next(httpContext);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class TestMiddlewareExtensions
{
public static IApplicationBuilder UseTest(this IApplicationBuilder builder)
{
return builder.UseMiddleware<TestMiddleware>();
}
}
不能直接修改form & querystring值,因为它们是read-only,只能尝试替换。
尝试像下面这样更改您的中间件:
public class TestMiddleware
{
private readonly RequestDelegate _next;
public TestMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var queryitems = httpContext.Request.Query.SelectMany(x => x.Value, (col, value) => new KeyValuePair<string, string>(col.Key, value)).ToList();
List<KeyValuePair<string, string>> queryparameters = new List<KeyValuePair<string, string>>();
foreach(var item in queryitems)
{
var value = item.Value.ToString().Replace("x", "y");
KeyValuePair<string, string> newqueryparameter = new KeyValuePair<string, string>(item.Key, value);
queryparameters.Add(newqueryparameter);
}
var contentType = httpContext.Request.ContentType;
if (contentType != null && contentType.Contains("multipart/form-data"))
{
var formitems = httpContext.Request.Form.SelectMany(x => x.Value, (col, value) => new KeyValuePair<string, string>(col.Key, value)).ToList();
Dictionary<string, StringValues> formparameters = new Dictionary<string, StringValues>();
foreach (var item in formitems)
{
var value = item.Value.ToString().Replace("x", "y");
formparameters.Add(item.Key, value);
};
var qb1 = new QueryBuilder(queryparameters);
var qb2 = new FormCollection(formparameters);
httpContext.Request.QueryString = qb1.ToQueryString();
httpContext.Request.Form = qb2;
var items2 = httpContext.Request.Query.SelectMany(x => x.Value, (col, value) => new KeyValuePair<string, string>(col.Key, value)).ToList();
var items3 = httpContext.Request.Form.SelectMany(x => x.Value, (col, value) => new KeyValuePair<string, string>(col.Key, value)).ToList();
}
await _next(httpContext);
}
}
public static class TestMiddlewareExtensions
{
public static IApplicationBuilder UseTest(this IApplicationBuilder builder)
{
return builder.UseMiddleware<TestMiddleware>();
}
}
结果:
更新 Invoke 方法如下。
public Task Invoke(HttpContext httpContext)
{
if (httpContext.Request.QueryString.HasValue)
{
QueryBuilder queryBuilder = new QueryBuilder();
foreach (var key in httpContext.Request.Query.Keys)
{
var realValue = httpContext.Request.Query[key];
var modifiedValue = HttpUtility.UrlDecode(realValue);
queryBuilder.Add(key, modifiedValue);
}
httpContext.Request.QueryString = queryBuilder.ToQueryString();
}
return _next(httpContext);
}
我已经创建了一个中间件 class。这个 class 的目的是对所有表单和查询字符串值进行一些更改,但是有一个问题!表单和查询字符串值是只读的,我无法更改它们。怎么办?
public class TestMiddleware
{
private readonly RequestDelegate _next;
public TestMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var collection = httpContext.Request.Query;
foreach (var item in collection)
{
collection[item.Key] = item.Value.ToString().Replace('x', 'y');
}
httpContext.Request.Query = collection;
var collection2 = httpContext.Request.Form;
foreach (var item in collection2)
{
collection2[item.Key] = item.Value.ToString().Replace('x', 'y');
}
httpContext.Request.Form = collection2;
await _next(httpContext);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class TestMiddlewareExtensions
{
public static IApplicationBuilder UseTest(this IApplicationBuilder builder)
{
return builder.UseMiddleware<TestMiddleware>();
}
}
不能直接修改form & querystring值,因为它们是read-only,只能尝试替换。
尝试像下面这样更改您的中间件:
public class TestMiddleware
{
private readonly RequestDelegate _next;
public TestMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var queryitems = httpContext.Request.Query.SelectMany(x => x.Value, (col, value) => new KeyValuePair<string, string>(col.Key, value)).ToList();
List<KeyValuePair<string, string>> queryparameters = new List<KeyValuePair<string, string>>();
foreach(var item in queryitems)
{
var value = item.Value.ToString().Replace("x", "y");
KeyValuePair<string, string> newqueryparameter = new KeyValuePair<string, string>(item.Key, value);
queryparameters.Add(newqueryparameter);
}
var contentType = httpContext.Request.ContentType;
if (contentType != null && contentType.Contains("multipart/form-data"))
{
var formitems = httpContext.Request.Form.SelectMany(x => x.Value, (col, value) => new KeyValuePair<string, string>(col.Key, value)).ToList();
Dictionary<string, StringValues> formparameters = new Dictionary<string, StringValues>();
foreach (var item in formitems)
{
var value = item.Value.ToString().Replace("x", "y");
formparameters.Add(item.Key, value);
};
var qb1 = new QueryBuilder(queryparameters);
var qb2 = new FormCollection(formparameters);
httpContext.Request.QueryString = qb1.ToQueryString();
httpContext.Request.Form = qb2;
var items2 = httpContext.Request.Query.SelectMany(x => x.Value, (col, value) => new KeyValuePair<string, string>(col.Key, value)).ToList();
var items3 = httpContext.Request.Form.SelectMany(x => x.Value, (col, value) => new KeyValuePair<string, string>(col.Key, value)).ToList();
}
await _next(httpContext);
}
}
public static class TestMiddlewareExtensions
{
public static IApplicationBuilder UseTest(this IApplicationBuilder builder)
{
return builder.UseMiddleware<TestMiddleware>();
}
}
结果:
更新 Invoke 方法如下。
public Task Invoke(HttpContext httpContext)
{
if (httpContext.Request.QueryString.HasValue)
{
QueryBuilder queryBuilder = new QueryBuilder();
foreach (var key in httpContext.Request.Query.Keys)
{
var realValue = httpContext.Request.Query[key];
var modifiedValue = HttpUtility.UrlDecode(realValue);
queryBuilder.Add(key, modifiedValue);
}
httpContext.Request.QueryString = queryBuilder.ToQueryString();
}
return _next(httpContext);
}