Skip to content

Instantly share code, notes, and snippets.

@tocalai
Last active November 18, 2022 01:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tocalai/45182c64168ada8e35107fa44796df5c to your computer and use it in GitHub Desktop.
Save tocalai/45182c64168ada8e35107fa44796df5c to your computer and use it in GitHub Desktop.
[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