ASP.NET Core 1.0中间件响应流如何改写为长尾?

2026-03-30 12:181阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计464个文字,预计阅读时间需要2分钟。

ASP.NET Core 1.0中间件响应流如何改写为长尾?

我想在我的ASP.NET Core 1.0项目中编写自定义中间件,它将取代原始框架的Http响应流到我的自定义流,以便我能执行读取/查找/写操作(原本不可能在原始框架的2层以上进行)。在下一步的代码中,我将开始实现这个中间件。

我想在我的ASP.NET Core 1.0项目中编写自定义中间件,它将取代原始框架的Http响应流到我自己的,所以我将能够对它执行读/寻/写操作(原来不可能在原来的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); } } }

以下代码的问题在于,有时在调用await responseStream.CopyToAsync(fullResponse)时,fullResponse流已经关闭;所以它抛出一个异常无法访问一个封闭的Stream.

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

我想知道:

ASP.NET Core 1.0中间件响应流如何改写为长尾?

>为什么会这样?
>怎么预防呢?
>我的解决方案是个好主意还是有另一种方法来替换响应流?

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

本文共计464个文字,预计阅读时间需要2分钟。

ASP.NET Core 1.0中间件响应流如何改写为长尾?

我想在我的ASP.NET Core 1.0项目中编写自定义中间件,它将取代原始框架的Http响应流到我的自定义流,以便我能执行读取/查找/写操作(原本不可能在原始框架的2层以上进行)。在下一步的代码中,我将开始实现这个中间件。

我想在我的ASP.NET Core 1.0项目中编写自定义中间件,它将取代原始框架的Http响应流到我自己的,所以我将能够对它执行读/寻/写操作(原来不可能在原来的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); } } }

以下代码的问题在于,有时在调用await responseStream.CopyToAsync(fullResponse)时,fullResponse流已经关闭;所以它抛出一个异常无法访问一个封闭的Stream.

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

我想知道:

ASP.NET Core 1.0中间件响应流如何改写为长尾?

>为什么会这样?
>怎么预防呢?
>我的解决方案是个好主意还是有另一种方法来替换响应流?

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