我正在使用 ASP.NET Core 1.0 RC2 创建一个公共(public) REST Api,并且喜欢记录传入请求和传出响应。
我创建了一个中间件类,它在调用 app.UseMvc() 之前添加到管道中;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseIOMiddleware();
app.UseMvc();
}
我的中间件类如下所示:
public class IOMiddleware
{
private readonly RequestDelegate _next;
public IOMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
LogRequest(context.Request);
await _next.Invoke(context);
}
private async void LogRequest(HttpRequest request)
{
using (var bodyReader = new StreamReader(request.Body))
{
string body = await bodyReader.ReadToEndAsync();
request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));
System.Diagnostics.Debug.Print(body);
}
}
}
我可以读取请求主体流并使用此示例倒回它:Rewind request body stream ,但我不确定如何读取响应主体,因为流不可读。
在 Web API 2.0 中我可以使用 HttpResponseMessage.Content.ReadAsByteArrayAsync() 方法,但我如何在 ASP.Net Core 1.0 RC2 中完成同样的事情?
最佳答案
问题是 request.Body
不可读,只能写 - 通常流会定期通过线路刷新到客户端。
您可以通过替换流和缓冲内容直到管道的其余部分完成来解决这个问题。
public class IOMiddleware
{
private readonly RequestDelegate _next;
public IOMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
await LogRequest(context.Request);
await LogResponseAndInvokeNext(context);
}
private async Task LogRequest(HttpRequest request)
{
using (var bodyReader = new StreamReader(request.Body))
{
string body = await bodyReader.ReadToEndAsync();
request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));
System.Diagnostics.Debug.Print(body);
}
}
private async Task LogResponseAndInvokeNext(HttpContext context)
{
using (var buffer = new MemoryStream())
{
//replace the context response with our buffer
var stream = context.Response.Body;
context.Response.Body = buffer;
//invoke the rest of the pipeline
await _next.Invoke(context);
//reset the buffer and read out the contents
buffer.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(buffer);
using (var bufferReader = new StreamReader(buffer))
{
string body = await bufferReader.ReadToEndAsync();
//reset to start of stream
buffer.Seek(0, SeekOrigin.Begin);
//copy our content to the original stream and put it back
await buffer.CopyToAsync(stream);
context.Response.Body = stream;
System.Diagnostics.Debug.Print($"Response: {body}");
}
}
}
}
关于c# - 如何在 ASP.NET Core 1.0 中记录 HTTP 响应主体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37855384/