【发布时间】:2014-04-17 19:43:15
【问题描述】:
我正在尝试使用 asp.net web api 实现文件上传系统,但遇到了问题。我正在尝试将多部分表单数据放入内存流中,以便可以根据服务层实现将其写入磁盘或 blob 存储。问题是它适用于小文件,但我正在尝试上传 291 MB 的文件并且它抛出内存不足异常。代码如下:
if (!Request.Content.IsMimeMultipartContent())
{
Request.CreateErrorResponse(HttpStatusCode.UnsupportedMediaType, "Request must be multipart.");
}
var provider = new MultipartMemoryStreamProvider();
try
{
await Request.Content.ReadAsMultipartAsync(provider);
var infoPart = provider.Contents.Where(x => x.Headers.ContentDisposition.Name.Replace("\"", string.Empty) == "fileInfo").SingleOrDefault();
var filePart = provider.Contents.Where(x => x.Headers.ContentDisposition.Name.Replace("\"", string.Empty) == "filePart" && x.Headers.ContentDisposition.FileName != null).Single();
byte[] file = null;
using (Stream stream = filePart.ReadAsStreamAsync().Result)
{
using (MemoryStream memory = new MemoryStream())
{
stream.CopyTo(memory);
file = memory.ToArray();
}
}
string fileContentType = filePart.Headers.ContentType.MediaType;
FileDto result = _fileService.AddFileToResource(Variables);
string uri = Url.Link("DefaultGet", new { id = result.ID });
return Request.CreateResponse(HttpStatusCode.OK);
引发错误的部分在
await Request.Content.ReadAsMultipartAsync(provider);
确切的错误是
将 MIME 多部分正文部分写入输出流时出错。
内部例外
引发了“System.OutOfMemoryException”类型的异常。
我已尝试创建自定义BufferPolicySelector,如this post 和许多其他地方的第二个答案所示,但这似乎根本没有帮助。
我也添加到了我的 web.config:
<httpRuntime targetFramework="4.5" maxRequestLength="307200"/>
和
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="367001600"/>
</requestFiltering>
</security>
【问题讨论】:
-
我在这里可能是错的,但是我阅读您的代码的方式,您将在这个 sn-p 的内存中拥有该文件的 3 个副本:请求内容流、内存流和字节数组文件。也许 reuqest 结果流将真正流式传输,但“内存”和“文件”将同时在 RAM 中。
-
感谢您的建议。我将如何改善这一点?它并没有真正帮助我的问题,因为它在读取 await Request.Content.ReadAsMultipartAsync(provider); 中的内容时会引发错误。但我绝对想了解如何使其尽可能高效
-
还要验证 maxRequestLength 应该大于或等于分配给 RequestLengthDiskThreshold 的值
-
是的,我这样做了,但是没有用
-
@gmoney12 很难为您重构它,因为很难说出您在其中到底在做什么。 'stream' 和 'file' 似乎没有被使用,因为我可以看到整个块可以被删除。
标签: c# asp.net asp.net-web-api