我有一个中间件来跟踪我在ASP.NET Core 2.2 API中自定义开发的网关的性能。我已经使用了StackOverflow的this post。
主要部分如下:
public class ResponseRewindMiddleware {
private readonly RequestDelegate next;
public ResponseRewindMiddleware(RequestDelegate next) {
this.next = next;
}
public async Task Invoke(HttpContext context) {
Stream originalBody = context.Response.Body;
/* MY CODE COMES HERE */
try {
using (var memStream = new MemoryStream()) {
context.Response.Body = memStream;
await next(context);
memStream.Position = 0;
string responseBody = new StreamReader(memStream).ReadToEnd();
memStream.Position = 0;
await memStream.CopyToAsync(originalBody);
}
} finally {
context.Response.Body = originalBody;
}
}
此代码运行正常。但是我想将输入(JSON主体)记录到网关,然后添加以下几行:
using (System.IO.StreamReader rd = new System.IO.StreamReader(context.Request.Body))
{
bodyStr = rd.ReadToEnd();
}
这将从Request中读取输入正文,但流程中断,其余流程未完成,从而导致“ HTTP 500 Internal Server Error”。我假设通过Stream读取Request正文有问题。
如何在不中断流程的情况下阅读请求正文?
想法是调用EnableBuffering以启用多次读取,然后在完成读取请求后不处理请求正文。以下对我有用。
// Enable the request body to be read in the future
context.Request.EnableBuffering();
// Read the request body, but do not dispose it
var stream = new StreamReader(context.Request.Body);
string requestBody = await stream.ReadToEndAsync();
// Reset to the origin so the next read would start from the beginning
context.Request.Body.Seek(0, SeekOrigin.Begin);