我一直在努力Response.Body从ASP.NET核心操作中获取属性,而我能够识别的唯一解决方案似乎不是最佳的.该解决方案需要Response.Body在一段MemoryStream时间内将流读取到字符串变量中,然后在发送到客户端之前将其交换回来.在下面的示例中,我试图Response.Body在自定义中间件类中获取值. Response.Body是一个集在ASP.NET核心出于某种原因唯一的财产?我在这里遗漏了什么,或者这是一个疏忽/错误/设计问题?有更好的阅读方式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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
尝试使用EnableRewind()的解决方案:
这仅适用于Request.Body,而不是Response.Body.这导致从而Response.Body不是实际的响应主体内容中读取空字符串. …
我正在重新实现一个请求记录器作为Owin Middleware,它记录所有传入请求的请求URL和正文.我能够读取正文,但是如果我在控制器中执行body参数则为null.
我猜它是空的,因为流的位置在最后,因此在尝试反序列化主体时没有什么可读的.我在以前版本的Web API中遇到了类似的问题,但是能够将Stream位置设置回0.这个特定的流引发This stream does not support seek operations异常.
在最新版本的Web API 2.0中,我可以Request.HttpContent.ReadAsStringAsync()在我的请求记录器内部调用,并且主体仍然可以直接到达控制器.
如何在阅读后回放流?
要么
如何在不消费的情况下阅读请求体?
public class RequestLoggerMiddleware : OwinMiddleware
{
public RequestLoggerMiddleware(OwinMiddleware next)
: base(next)
{
}
public override Task Invoke(IOwinContext context)
{
return Task.Run(() => {
string body = new StreamReader(context.Request.Body).ReadToEnd();
// log body
context.Request.Body.Position = 0; // cannot set stream position back to 0
Console.WriteLine(context.Request.Body.CanSeek); // prints false
this.Next.Invoke(context);
});
}
}
Run Code Online (Sandbox Code Playgroud)
public class SampleController : ApiController
{
public void Post(ModelClass …Run Code Online (Sandbox Code Playgroud)