ASP.NET 核心 modify/substitute 请求正文
ASP.NET Core modify/substitute request body
我想在 HttpContext.Request.Body
上进行替换。
我试过在中间件中完成:
public async Task Invoke(HttpContext context)
{
if (context.Request.Path.Value.Contains("DataSourceResult"))
{
var originalBody = new StreamReader(context.Request.Body).ReadToEnd();
DataSourceRequest dataSource = null;
try
{
dataSource = JsonConvert.DeserializeObject<DataSourceRequest>(originalBody);
} catch
{
await _next.Invoke(context);
}
if (dataSource != null && dataSource.Take > 2000)
{
dataSource.Take = 2000;
var bytesToWrite = dataSource.AsByteArray();
await context.Request.Body.WriteAsync(bytesToWrite, 0, bytesToWrite.Length);
}
else
{
var bytesToWrite = originalBody.AsByteArray();
await context.Request.Body.WriteAsync(bytesToWrite, 0, bytesToWrite.Length);
}
}
await _next.Invoke(context);
}
第一个问题是body只能读一次,其次stream是只读的,不能写。
我怎样才能modify/substituteRequest.Body
?我需要更改请求正文的 属性 值。
获取请求正文,读取其内容,进行任何必要的更改(如果有的话),然后创建一个新流以向下传递管道。一旦访问,请求流必须被替换。
public async Task Invoke(HttpContext context) {
var request = context.Request;
if (request.Path.Value.Contains("DataSourceResult")) {
//get the request body and put it back for the downstream items to read
var stream = request.Body;// currently holds the original stream
var originalContent = new StreamReader(stream).ReadToEnd();
var notModified = true;
try {
var dataSource = JsonConvert.DeserializeObject<DataSourceRequest>(originalContent);
if (dataSource != null && dataSource.Take > 2000) {
dataSource.Take = 2000;
var json = JsonConvert.SerializeObject(dataSource);
//replace request stream to downstream handlers
var requestContent = new StringContent(json, Encoding.UTF8, "application/json");
stream = await requestContent.ReadAsStreamAsync();//modified stream
notModified = false;
}
} catch {
//No-op or log error
}
if (notModified) {
//put original data back for the downstream to read
var requestData = Encoding.UTF8.GetBytes(originalContent);
stream = new MemoryStream(requestData);
}
request.Body = stream;
}
await _next.Invoke(context);
}
在我的例子中,还需要将 Request.ContentLength 更新为新值。
我的解决方案是:
string originalContent;
using (StreamReader stream = new StreamReader(context.Request.Body))
{
originalContent = stream.ReadToEnd();
}
var dataSource = JsonConvert.DeserializeObject<DataSourceRequest>(originalContent);
if (dataSource != null && dataSource.Take > 2000)
dataSource.Take = 2000;
string json = JsonConvert.SerializeObject(dataSource);
var requestData = Encoding.UTF8.GetBytes(json);
context.Request.Body = new MemoryStream(requestData);
context.Request.ContentLength = context.Request.Body.Length;
我想在 HttpContext.Request.Body
上进行替换。
我试过在中间件中完成:
public async Task Invoke(HttpContext context)
{
if (context.Request.Path.Value.Contains("DataSourceResult"))
{
var originalBody = new StreamReader(context.Request.Body).ReadToEnd();
DataSourceRequest dataSource = null;
try
{
dataSource = JsonConvert.DeserializeObject<DataSourceRequest>(originalBody);
} catch
{
await _next.Invoke(context);
}
if (dataSource != null && dataSource.Take > 2000)
{
dataSource.Take = 2000;
var bytesToWrite = dataSource.AsByteArray();
await context.Request.Body.WriteAsync(bytesToWrite, 0, bytesToWrite.Length);
}
else
{
var bytesToWrite = originalBody.AsByteArray();
await context.Request.Body.WriteAsync(bytesToWrite, 0, bytesToWrite.Length);
}
}
await _next.Invoke(context);
}
第一个问题是body只能读一次,其次stream是只读的,不能写。
我怎样才能modify/substituteRequest.Body
?我需要更改请求正文的 属性 值。
获取请求正文,读取其内容,进行任何必要的更改(如果有的话),然后创建一个新流以向下传递管道。一旦访问,请求流必须被替换。
public async Task Invoke(HttpContext context) {
var request = context.Request;
if (request.Path.Value.Contains("DataSourceResult")) {
//get the request body and put it back for the downstream items to read
var stream = request.Body;// currently holds the original stream
var originalContent = new StreamReader(stream).ReadToEnd();
var notModified = true;
try {
var dataSource = JsonConvert.DeserializeObject<DataSourceRequest>(originalContent);
if (dataSource != null && dataSource.Take > 2000) {
dataSource.Take = 2000;
var json = JsonConvert.SerializeObject(dataSource);
//replace request stream to downstream handlers
var requestContent = new StringContent(json, Encoding.UTF8, "application/json");
stream = await requestContent.ReadAsStreamAsync();//modified stream
notModified = false;
}
} catch {
//No-op or log error
}
if (notModified) {
//put original data back for the downstream to read
var requestData = Encoding.UTF8.GetBytes(originalContent);
stream = new MemoryStream(requestData);
}
request.Body = stream;
}
await _next.Invoke(context);
}
在我的例子中,还需要将 Request.ContentLength 更新为新值。 我的解决方案是:
string originalContent;
using (StreamReader stream = new StreamReader(context.Request.Body))
{
originalContent = stream.ReadToEnd();
}
var dataSource = JsonConvert.DeserializeObject<DataSourceRequest>(originalContent);
if (dataSource != null && dataSource.Take > 2000)
dataSource.Take = 2000;
string json = JsonConvert.SerializeObject(dataSource);
var requestData = Encoding.UTF8.GetBytes(json);
context.Request.Body = new MemoryStream(requestData);
context.Request.ContentLength = context.Request.Body.Length;