I am trying to implement a file upload system with asp.net web api and I am running into a problem. I am trying to get the multipart form data into a memory stream so it can be written to either disk or blob storage depending on the service layer implementation. The problem is it works fine for small files but I am trying to upload a file of 291 MB and it is throwing an out of memory exception. Here is the code:
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);
The part that throws the error is on the
await Request.Content.ReadAsMultipartAsync(provider);
The exact error is
Error writing MIME multipart body part to output stream.
with inner exception of
Exception of type 'System.OutOfMemoryException' was thrown.
I have tried creating a custom BufferPolicySelector as shown in the second answer of this post and many other places but that doesn't seem to help at all.
I have also added to my web.config:
<httpRuntime targetFramework="4.5" maxRequestLength="307200"/>
and
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="367001600"/>
</requestFiltering>
</security>
One solution would be to use MultipartFormDataStreamProvider instead of the MultipartMemoryStreamProvider to avoid the out of memory exception during the call
Request.Content.ReadAsMultipartAsync(..)
I was facing a similar problem while trying to use a MemoryStreamProvider while reading the MultiPart file contents for a large file (> 100 MB). The work around that worked for me was to use MultipartFormDataStreamProvider. The file is written to the disk during the ReadAsMultipartAsync call and can be later loaded back in if you need it in memory.
Here is an example taken from:
Sending HTML Form Data in Web API: File Upload and Multipart MIME
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the file names.
foreach (MultipartFileData file in provider.FileData)
{
Trace.WriteLine(file.Headers.ContentDisposition.FileName);
Trace.WriteLine("Server file path: " + file.LocalFileName);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch(...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With