M. *_*ann 6 c# asp.net-web-api
我创建了一个基于MVC 5的WebAPI控制器 - 为我们的客户提供不同的文件.访问文件的工具也是自编写的 - 基于.NET HttpClient - 但这是另一个故事.
在下载控制器的第一个版本,我使用的生成机制来提供像文件这样
但是这个机制在我的iis上崩溃了4GB以上的文件.
所以我终于来到了这段代码:
public class DownloadController : ApiController
{
public async Task Get(long id)
{
string fullFilePath = GetFilePathById(id);
string returnFileName = fullFilePath.Split('\\').Last();
FileInfo path = new FileInfo(fullFilePath);
HttpContext.Current.Response.ContentType = "application/zip";
HttpContext.Current.Response.AddHeader("Content-Length", path.Length.ToString());
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + returnFileName);
HttpContext.Current.Response.Flush();
try
{
byte[] buffer = new byte[4096];
using (FileStream fs = path.OpenRead())
{
using (BufferedStream bs = new BufferedStream(fs, 524288))
{
int count = 0;
while ((count = bs.Read(buffer, 0, buffer.Length)) > 0)
{
if (!HttpContext.Current.Response.IsClientConnected)
{
break;
}
HttpContext.Current.Response.OutputStream.Write(buffer, 0, count);
HttpContext.Current.Response.Flush();
}
}
}
}
catch (Exception exception)
{
//Exception logging here
}
}
}
Run Code Online (Sandbox Code Playgroud)
该代码运行良好,我可以通过可接受的CPU使用率和磁盘i/o获得快速下载.但过了一段时间后,我注意到 - 每次下载 - 一个未处理的异常将一个条目写入IIS服务器的Application Eventlog,如下所示:
Server cannot set status after HTTP headers have been sent
Exception type: HttpException
Event Log ID 1309
Run Code Online (Sandbox Code Playgroud)
我确信反复使用.Flush()会导致问题,但是如果我删除其中任何一个,下载就会停止工作.
在类似的问题中,我可以找到Response.BufferOutput = true;解决方案,但这似乎占用了我所有的服务器资源并延迟了下载.
任何建议都会很棒!
问题不在于Flush(),而是您没有自己关闭响应流HttpContext.Current.Response.Close();
ASP.NET 框架不知道您在操作方法内做什么,因此它通过通常的请求管道传递请求,该管道代替我们完成所有必要的管道工作。其中之一是将标头和 HTTP 状态发送到客户端。但是,当框架尝试这样做时,您已经设置并发送了标头。为了避免这种情况,您应该关闭流,并通过关闭响应流来完成处理。
| 归档时间: |
|
| 查看次数: |
658 次 |
| 最近记录: |