gpt4 book ai didi

asp.net-core - 替换 ASP.NET Core 1.0 中间件中的响应流

转载 作者:行者123 更新时间:2023-12-04 01:36:49 24 4
gpt4 key购买 nike

我想在我的 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); 所以它抛出异常Cannot access a closed Stream.

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

我想知道:

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

最佳答案

异常并非来自您的 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!");
});

关于asp.net-core - 替换 ASP.NET Core 1.0 中间件中的响应流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38285623/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com