【问题标题】:Replacing response stream in ASP.NET Core 1.0 middleware替换 ASP.NET Core 1.0 中间件中的响应流
【发布时间】:2016-11-12 03:24:45
【问题描述】:

我想在我的 ASP.NET Core 1.0 项目中编写自定义中间件,它将原始框架的 Http Response Stream 替换为我自己的,因此我将能够对其执行读/查找/写操作(前 2 个是不可能的在原始流上)在进一步的代码中,即在操作或过滤器中。

我从以下代码开始:

public class ReplaceStreamMiddleware
{
    protected RequestDelegate NextMiddleware;

    public ReplaceStreamMiddleware(RequestDelegate next)
    {
        NextMiddleware = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {       
        using (var responseStream = new MemoryStream())
        {
            var fullResponse = httpContext.Response.Body;
            httpContext.Response.Body = responseStream;
            await NextMiddleware.Invoke(httpContext);
            responseStream.Seek(0, SeekOrigin.Begin);
            await responseStream.CopyToAsync(fullResponse);
        }   
    }
}

以下代码的问题在于有时fullResponse 流在调用await responseStream.CopyToAsync(fullResponse);已经关闭,因此它会引发异常无法访问已关闭的 Stream。

当我在浏览器中加载页面然后刷新时很容易观察到这种奇怪的行为,在它完全加载之前

我想知道:

  1. 为什么会这样?
  2. 如何预防?
  3. 我的解决方案是个好主意还是有其他方法可以替换响应流?

【问题讨论】:

    标签: asp.net-core asp.net-core-1.0 asp.net-core-middleware


    【解决方案1】:

    异常并非来自您的CopyToAsync。它来自您的代码调用者之一:

    您没有恢复 HttpContext 中的原始响应流。因此,无论谁调用你的中间件,都会得到一个封闭的MemoryStream

    这是一些工作代码:

    app.Use(async (httpContext, next) =>
    {
        using (var memoryResponse = new MemoryStream())
        {
            var originalResponse = httpContext.Response.Body;
            try
            {
                httpContext.Response.Body = memoryResponse;
    
                await next.Invoke();
    
                memoryResponse.Seek(0, SeekOrigin.Begin);
                await memoryResponse.CopyToAsync(originalResponse);
            }
            finally
            {
                // This is what you're missing
                httpContext.Response.Body = originalResponse;
            }
        }
    });
    
    app.Run(async (context) =>
    {
        context.Response.ContentType = "text/other";
        await context.Response.WriteAsync("Hello World!");
    });
    

    【讨论】:

      猜你喜欢
      • 2016-07-04
      • 2016-01-05
      • 1970-01-01
      • 2016-10-17
      • 1970-01-01
      • 2017-08-23
      • 1970-01-01
      • 1970-01-01
      • 2020-08-03
      相关资源
      最近更新 更多