在owin中间件中读取响应体

Reading the response body in owin middleware

我试图在我的 MVC 控制器操作执行后获取响应的副本,但是从这里的其他问题我无法使这段代码工作(尽管这似乎是一个很好回答的问题)。 ..

public class Startup
{
   public void Configuration(IAppBuilder app)
   {
     app.Use(async (context, next) =>
     {
        var resultStream = context.Response.Body;
        context.Response.Body = new MemoryStream();

        // allow the response to be written in future request lifecycle events
        await next.Invoke();

        // fetch the repsonse
        context.Response.Body.Seek(0, SeekOrigin.Begin);
        var headers = context.Response.Headers;
        var body = new StreamReader(context.Response.Body).ReadToEnd();

        // ... other code omitted for question clarity

        // write the response to the client
        context.Response.Body.Seek(0, SeekOrigin.Begin);
        await context.Response.Body.CopyToAsync(resultStream);
        context.Response.Body = resultStream;
      });
   }

   // ... other code omitted for question clarity
}

当我到达第二个时,变量 "body" 为空。

知道为什么当此后的结果是包含内容的页面时会出现这种情况吗?

原来这里的问题是因为 Owin 和 asp.net 并没有像我想象的那样在整个生命周期中交织在一起。

简而言之,请求生命周期类似于...

  1. 做 Owin 的东西(所有 owin 中间件)
  2. 做 MVC 的东西
  3. 做服务器的事情

...我需要的是...

  1. 做自己的事情
  2. 做 MVC 的东西
  3. 做更多欧文的事情
  4. 做服务器的事情

...当然,我在这里过度简化了过程,但我想解释它的最简单方法是当您...

app.Use((context, next) => { ... }).UsestageMarker(?);

..."response processing complete".

没有阶段标记

有趣的是,aspnet core 为我们提供了更多的控制权,因为在整个请求生命周期中与所有部分的紧密集成较少依赖于预定义的阶段,更多的是关于您定义自己的处理请求和构建响应的过程的用户。

简而言之...在 aspnet 核心中,我可以做我想做的事,但这在 owin 中似乎不可能与 .net 4.6

但是我做了一些关于使用过滤器和处理的参考 "OnActionExectuted" 如果你看起来你有一个与 owin 中间件管道给你的完全不同的请求和响应对象(因此增加了更多证据表明这些事情实际上不是一个单一的过程,而是两个按顺序发生的过程。

从那以后,我一直在研究如何将我的应用程序迁移到 aspnet 核心......事实证明,这比我预期的更令人头疼,但我一直希望最终结果更干净、更快.