我一直在努力获取ASP.NET Core操作中的Response.Body
属性,但唯一能够识别的解决方案似乎不太理想。该解决方案要求使用MemoryStream
替换Response.Body
,同时将流读取到一个字符串变量中,然后在发送到客户端之前再将其替换回去。在下面的示例中,我正在尝试在自定义中间件类中获取Response.Body
值。由于某种原因,在ASP.NET Core中,Response.Body
是只写属性?我是否遗漏了什么,或者这是一个疏忽/错误/设计问题?有更好的方法来读取Response.Body
吗?
当前(不太理想的)解决方案:
public class MyMiddleWare
{
private readonly RequestDelegate _next;
public MyMiddleWare(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
using (var swapStream = new MemoryStream())
{
var originalResponseBody = context.Response.Body;
context.Response.Body = swapStream;
await _next(context);
swapStream.Seek(0, SeekOrigin.Begin);
string responseBody = new StreamReader(swapStream).ReadToEnd();
swapStream.Seek(0, SeekOrigin.Begin);
await swapStream.CopyToAsync(originalResponseBody);
context.Response.Body = originalResponseBody;
}
}
}
使用EnableRewind()的尝试解决方案:
这只适用于Request.Body
,而不是 Response.Body
。 这会导致从Response.Body
读取空字符串,而不是实际的响应正文内容。
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifeTime)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.Use(async (context, next) => {
context.Request.EnableRewind();
await next();
});
app.UseMyMiddleWare();
app.UseMvc();
// Dispose of Autofac container on application stop
appLifeTime.ApplicationStopped.Register(() => this.ApplicationContainer.Dispose());
}
MyMiddleWare.cs
public class MyMiddleWare
{
private readonly RequestDelegate _next;
public MyMiddleWare(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
await _next(context);
string responseBody = new StreamReader(context.Request.Body).ReadToEnd(); //responseBody is ""
context.Request.Body.Position = 0;
}
}