asp.net - 倒带请求正文流

标签 asp.net .net asp.net-web-api owin owin-middleware

我正在将请求记录器重新实现为Owin中间件,该记录器记录了所有输入请求的请求URL和主体。 我可以读取正文,但是如果执行此操作,则 Controller 中的body参数为null。

我猜这是空的,因为流的位置在末尾,因此在尝试反序列化正文时没有什么可读取的。在先前版本的Web API中,我也遇到了类似的问题,但是能够将Stream位置设置回0。此特定的流引发This stream does not support seek operations异常。

在最新版本的Web API 2.0中,我可以在请求记录器中调用Request.HttpContent.ReadAsStringAsync(),并且正文仍可以完整地到达 Controller 。

阅读后如何重播流?

要么

如何在不使用请求主体的情况下阅读它?

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);
        });
    }
}
public class SampleController : ApiController 
{
    public void Post(ModelClass body)
    {
        // body is now null if the middleware reads it
    }
}

最佳答案

刚找到一个解决方案。用包含数据的新流替换原始流。

    public override Task Invoke(IOwinContext context)
    {
        return Task.Run(() => {
            string body = new StreamReader(context.Request.Body).ReadToEnd();
            // log body

            byte[] requestData = Encoding.UTF8.GetBytes(body);
            context.Request.Body = new MemoryStream(requestData);
            this.Next.Invoke(context);
        });
    }

如果您要处理大量数据,我相信FileStream也可以替代。

关于asp.net - 倒带请求正文流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21805362/

相关文章:

c# - 间歇性 WCF 激活错误

c# - 我可以使用具有两个不同母版页的相同内容页吗?

c# - 使用 NEST 索引动态对象

c# - 如何处理 Autofac 容器?

.net - Web API 中的异常日志记录

asp.net - 组件化的 ASP.NET MVC 应用程序是否可以顺利部署?

html - 无法将 Logo 居中

c# - 我该如何解决此错误 :"Column ' ASSET' 不属于表。”?

asp.net - Web API个人账户注册用户

.net - BITS 客户端无法指定 HTTP Range header