我的控制器上有一个操作,应该上传大型(500mb - 2gb)文件。例如,
[HttpPost]
public void PostFile([FromUri]Guid uploadId)
{
...
}
在正文内部,执行一些检查(例如 uploadId 是否存在),然后将 HTTP 请求的发布正文写入磁盘(/网络共享)。
我以为我已经解决了这个问题,因为如果没有创建 uploadId,我可以通过抛出 HttpResponseException 几乎立即拒绝 HTTP 请求,但我刚刚发现即使在这种情况下,请求的主体也会完全上传到服务器并保存到磁盘的 ASP.Net Temporary Files 文件夹。这意味着客户端必须完全上传文件(大约需要 5-10 分钟)才能发现该文件已被服务器拒绝。
我该如何避免这种情况?有什么方法可以阻止 IIS 将主体写入磁盘并允许控制器处理流吗?我发现令人沮丧的是,客户端开始上传和请求命中我自己的代码之间有 5 分钟的延迟,因为 ASP.Net 必须做自己的事情并将上传写入本地磁盘。
EDIT
有人问我如何读取上传数据。本质上,使用这种方法:
/// <summary>
/// Saves the current request's upload stream to the proivded path.
/// </summary>
/// <param name="destinationPath">The path to save to.</param>
/// <returns></returns>
private async Task<FileInfo> SaveUploadToDiskAsync(string destinationPath)
{
using (var httpContent = Request.Content)
{
using (FileStream fileStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
{
await httpContent.CopyToAsync(fileStream);
return new FileInfo(destinationPath);
}
}
}
您可以通过实现自定义的方法将 Web API 配置为在特定控制器(或全局)的无缓冲模式(流式传输)下工作WebHostBufferPolicySelector
public class NoBufferPolicySelector : WebHostBufferPolicySelector
{
public override bool UseBufferedInputStream(object hostContext)
{
var context = hostContext as HttpContextBase;
if (context != null)
{
if (string.Equals(context.Request.RequestContext.RouteData.Values["controller"].ToString(), "upload", StringComparison.InvariantCultureIgnoreCase))
return false;
}
return true;
}
public override bool UseBufferedOutputStream(HttpResponseMessage response)
{
return base.UseBufferedOutputStream(response);
}
}
我已经写了一个演练在Web API中处理大文件 http://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)