如何在ASP.NET核心中间件中直接设置文件流的响应体? [英] How to directly set response body to a file stream in ASP.NET Core middleware?
本文介绍了如何在ASP.NET核心中间件中直接设置文件流的响应体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在ASP.NET核心中间件中将文件流写入Response.Body
的以下示例代码不起作用(发出空响应):
public Task Invoke(HttpContext context)
{
context.Response.ContentType = "text/plain";
using (var fs = new FileStream("/valid-path-to-file-on-server.txt", FileMode.Open)
using (var sr = new StreamReader(fs))
{
context.Response.Body = sr.BaseStream;
}
return Task.CompletedTask;
}
您认为这种直接设置context.Response.Body
的方法有什么问题吗?
注意:将跳过管道中的任何下一个中间件,不再进行进一步处理。
更新(另一个示例):简单的MemoryStream
赋值也不起作用(空响应):
context.Response.Body = new MemoryStream(Encoding.UTF8.GetBytes(DateTime.Now.ToString()));
推荐答案
不是。您永远不能直接这样做。
请注意,
context.Response.Body
是对对象(HttpResponseStream
)的引用,initialized before它在HttpContext
中可用。假设所有字节都写入此原始流。如果您通过context.Response.Body = a_new_Stream
将Body
更改为引用(指向)新的流对象,则原始的Stream
根本不会更改。此外,如果您查看
ASP.NET Core
的源代码,您会发现团队总是将包装流复制到末尾的原始正文流,而不是使用简单的替换(除非他们正在使用模拟的流进行单元测试)。例如SPA Prerendering middleware源代码:finally { context.Response.Body = originalResponseStream; ...
和
ResponseCachingMiddleware
源代码:public async Task Invoke(HttpContext httpContext) { ... finally { UnshimResponseStream(context); } ... } internal static void UnshimResponseStream(ResponseCachingContext context) { // Unshim response stream context.HttpContext.Response.Body = context.OriginalResponseStream; // Remove IResponseCachingFeature RemoveResponseCachingFeature(context.HttpContext); }
作为漫游,您可以将字节复制到原始流,如下所示:
public async Task Invoke(HttpContext context) { context.Response.ContentType = "text/plain"; using (var fs = new FileStream("valid-path-to-file-on-server.txt", FileMode.Open)) { await fs.CopyToAsync(context.Response.Body); } }
或者如果您喜欢劫持原始
HttpResponseStream
,请使用您自己的流包装:var originalBody = HttpContext.Response.Body; var ms = new MemoryStream(); HttpContext.Response.Body = ms; try { await next(); HttpContext.Response.Body = originalBody; ms.Seek(0, SeekOrigin.Begin); await ms.CopyToAsync(HttpContext.Response.Body); } finally { response.Body = originalBody; }
这篇关于如何在ASP.NET核心中间件中直接设置文件流的响应体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文