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 }; }