Nic*_*ick 7 asp.net-core asp.net-core-middleware asp.net-core-webapi razor-pages
下面将文件流写入Response.Body
ASP.NET Core 中间件的示例代码不起作用(发出空响应):
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;
}
Run Code Online (Sandbox Code Playgroud)
任何想法直接设置context.Response.Body
?
注意:管道中的任何下一个中间件都将被跳过,不再进行进一步处理。
更新(另一个例子):一个简单的MemoryStream
分配也不起作用(空响应):
context.Response.Body = new MemoryStream(Encoding.UTF8.GetBytes(DateTime.Now.ToString()));
Run Code Online (Sandbox Code Playgroud)
itm*_*nus 11
不,你永远不能直接这样做。
注意,context.Response.Body
是为一个对象(基准HttpResponseStream
),其之前初始化它成为可用HttpContext
。假设所有字节都写入这个原始流。如果您将Body
to 引用(指向)一个新的流对象更改为context.Response.Body = a_new_Stream
,则原始流对象Stream
根本不会更改。
此外,如果您查看 的源代码ASP.NET Core
,您会发现团队总是在最后将包装流复制到原始正文流,而不是简单的替换(除非他们使用模拟流进行单元测试)。例如,SPA Prerendering 中间件源代码:
finally
{
context.Response.Body = originalResponseStream;
...
Run Code Online (Sandbox Code Playgroud)
和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);
}
Run Code Online (Sandbox Code Playgroud)
作为一种解决方法,您可以将字节复制到原始流,如下所示:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您想使用自己的流包装器劫持原始数据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;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4768 次 |
最近记录: |