Last active
November 18, 2022 01:26
-
-
Save tocalai/45182c64168ada8e35107fa44796df5c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Route("api/[controller]")] | |
public class FileController : ControllerBase | |
{ | |
[HttpPost("uploadlarge")] | |
[DisableFormValueModelBinding] | |
public async Task<IActionResult> UploadLargeFileAsync() | |
{ | |
try | |
{ | |
if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType)) | |
{ | |
throw new FormatException("Form without multipart content."); | |
} | |
var subDirectory = string.Empty; | |
var count = 0; | |
var totalSize = 0L; | |
// find the boundary | |
var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType)); | |
// use boundary to iterator through the multipart section | |
var reader = new MultipartReader(boundary, HttpContext.Request.Body); | |
var section = await reader.ReadNextSectionAsync(); | |
do | |
{ | |
ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition); | |
if (!MultipartRequestHelper.HasFileContentDisposition(contentDisposition)) | |
{ | |
if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition) && contentDisposition.Name == nameof(subDirectory)) | |
{ | |
using var streamReader = new StreamReader(section.Body, Encoding.UTF8); | |
// get the subdirectory first | |
subDirectory = streamReader.ReadToEnd(); | |
} | |
section = await reader.ReadNextSectionAsync(); | |
continue; | |
} | |
totalSize += await SaveFileAsync(section, subDirectory); | |
count++; | |
section = await reader.ReadNextSectionAsync(); | |
} while (section != null); | |
return Ok(new { Count = count, Size = SizeConverter(totalSize) }); | |
} | |
catch (Exception exception) | |
{ | |
return BadRequest($"Error: {exception.Message}"); | |
} | |
} | |
private async Task<long> SaveFileAsync(MultipartSection section, string subDirectory) | |
{ | |
subDirectory ??= string.Empty; | |
var target = Path.Combine("{root}", subDirectory); | |
Directory.CreateDirectory(target); | |
var fileSection = section.AsFileSection(); | |
var filePath = Path.Combine(target, fileSection.FileName); | |
using var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 1024); | |
await fileSection.FileStream.CopyToAsync(stream); | |
return fileSection.FileStream.Length; | |
} | |
private string SizeConverter(long bytes) | |
{ | |
var fileSize = new decimal(bytes); | |
var kilobyte = new decimal(1024); | |
var megabyte = new decimal(1024 * 1024); | |
var gigabyte = new decimal(1024 * 1024 * 1024); | |
switch (fileSize) | |
{ | |
case var _ when fileSize < kilobyte: | |
return $"Less then 1KB"; | |
case var _ when fileSize < megabyte: | |
return $"{Math.Round(fileSize / kilobyte, 0, MidpointRounding.AwayFromZero):##,###.##}KB"; | |
case var _ when fileSize < gigabyte: | |
return $"{Math.Round(fileSize / megabyte, 2, MidpointRounding.AwayFromZero):##,###.##}MB"; | |
case var _ when fileSize >= gigabyte: | |
return $"{Math.Round(fileSize / gigabyte, 2, MidpointRounding.AwayFromZero):##,###.##}GB"; | |
default: | |
return "n/a"; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment