DEV Community

Afshar Mohebi
Afshar Mohebi

Posted on

Upload file in ASP.NET Core

One task of mine includes uploading file in ASP.NET Core 5. Last time I did file upload in ASP.NET, I did it with IFormFile. However, this time I preferred to make a research if anything is changed so far. I came to sample code from Microsoft which is based a non-argument action. I copied the MS to following sample and put an IFromFile sample besides it to be referenced together.

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace upload.Controllers
{
    [ApiController]
    public class UploaderController : ControllerBase
    {
        [HttpPost]
        [Route("UploadModelBinding")]
        public async Task<IActionResult> UploadModelBinding(ICollection<IFormFile> files)
        {
            //model binding or model validation

            try
            {
                long size = files.Sum(f => f.Length);
                var fileName = Path.GetRandomFileName();
                var saveToPath = Path.Combine(Path.GetTempPath(), fileName);

                foreach (var formFile in files)
                {
                    if (formFile.Length > 0)
                    {
                        using (var stream = new FileStream(saveToPath, FileMode.Create))
                        {
                            await formFile.CopyToAsync(stream);
                        }
                    }
                }

                return Ok(new { count = files.Count, fileName, size, saveToPath });
            }
            catch (Exception exp)
            {
                return BadRequest("Exception generated when uploading file - " + exp.Message);
            }
        }

        [HttpPost]
        [Route("UploadNoArg")]
        public async Task<IActionResult> UploadNoArg()
        {
            //no-argument action

            var request = HttpContext.Request;

            if (!request.HasFormContentType ||
                !MediaTypeHeaderValue.TryParse(request.ContentType, out var mediaTypeHeader) ||
                string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
            {
                return new UnsupportedMediaTypeResult();
            }

            var reader = new MultipartReader(mediaTypeHeader.Boundary.Value, request.Body);
            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
                    out var contentDisposition);

                if (hasContentDispositionHeader && contentDisposition.DispositionType.Equals("form-data") &&
                    !string.IsNullOrEmpty(contentDisposition.FileName.Value))
                {
                    var fileName = Path.GetRandomFileName();
                    var saveToPath = Path.Combine(Path.GetTempPath(), fileName);

                    using (var targetStream = System.IO.File.Create(saveToPath))
                    {
                        await section.Body.CopyToAsync(targetStream);
                    }

                    return Ok();
                }

                section = await reader.ReadNextSectionAsync();
            }

            return BadRequest("No files data in the request.");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

I tested both methods using Postman. Both use form-data and an entry of type file. The only difference is that the model binding method requires that the entry to be named files. Consider that one methods is using model binding or model validation and another one is using no-argument action technique.

Discussion (0)