Uploading Large Files in ASP.NET Core
Enabling Kestrel Support for the Large Files
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxRequestBodySize = long.MaxValue;
});
public class FileUploadSummary
{
public int TotalFilesUploaded { get; set; }
public string TotalSizeUploaded { get; set; }
public IList<string> FilePaths { get; set; } = new List<string>();
public IList<string> NotUploadedFiles { get; set; } = new List<string>();
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class MultipartFormDataAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var request = context.HttpContext.Request;
if (request.HasFormContentType
&& request.ContentType.StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase))
{
return;
}
context.Result = new StatusCodeResult(StatusCodes.Status415UnsupportedMediaType);
}
}
Upload Large Files Using Streams
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var factories = context.ValueProviderFactories;
factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<FormFileValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
[HttpPost("upload-stream-multipartreader")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status415UnsupportedMediaType)]
[MultipartFormData]
[DisableFormValueModelBinding]
public async Task<IActionResult> Upload()
{
var fileUploadSummary = await _fileService.UploadFileAsync(HttpContext.Request.Body, Request.ContentType);
return CreatedAtAction(nameof(Upload), fileUploadSummary);
}
public async Task<FileUploadSummary> UploadFileAsync(Stream fileStream, string contentType)
{
var fileCount = 0;
long totalSizeInBytes = 0;
var boundary = GetBoundary(MediaTypeHeaderValue.Parse(contentType));
var multipartReader = new MultipartReader(boundary, fileStream);
var section = await multipartReader.ReadNextSectionAsync();
var filePaths = new List<string>();
var notUploadedFiles = new List<string>();
while (section != null)
{
var fileSection = section.AsFileSection();
if (fileSection != null)
{
totalSizeInBytes += await SaveFileAsync(fileSection, filePaths, notUploadedFiles);
fileCount++;
}
section = await multipartReader.ReadNextSectionAsync();
}
return new FileUploadSummary
{
TotalFilesUploaded = fileCount,
TotalSizeUploaded = ConvertSizeToString(totalSizeInBytes),
FilePaths = filePaths,
NotUploadedFiles = notUploadedFiles
};
}