Я изо всех сил пытался получить свойство Response.Body
из действия ASP.NET Core, и единственное решение, которое я смог определить, кажется неоптимальным. Решение требует замены Response.Body
на MemoryStream
при чтении потока в строковую переменную, а затем обменять его перед отправкой клиенту. В приведенных ниже примерах я пытаюсь получить значение Response.Body
в пользовательском классе промежуточного программного обеспечения. Response.Body
это свойство только для набора в ASP.NET Core по какой-то причине? Я просто что-то здесь упускаю, или это проблема надзора/ошибки/дизайна? Есть ли лучший способ читать 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;
}
}