Uploading Multiple Files in ASPNET Core Razor Pages

Uploading Multiple Files in ASP.NET Core Razor Pages

If you are a fan of ASP.NET Web forms and miss them, ASP.NET Core Razor Pages gives you the exact same feeling of ASP.NET Web forms. Razor Pages are a new feature of ASP.NET Core 2.0 that makes coding page-focused scenarios easier and more productive. Razor Pages are introduced with the intent of creating page focused scenarios where there is no real logic is involved. This short post talks about the solution for uploading multiple files in ASP.NET Core Razor Pages using jQuery and Ajax.

Uploading Multiple Files in ASP.NET Core Razor Pages

Let’s create an ASP.NET Core Razor Page application. You should see the following dialog box when you create a new ASP.NET Core web application.

Create new Razor Page application If you are not seeing this, then update your Visual Studio 2017 and install .NET Core 2.0 from here.

Let’s take a look at the HTML code (.cshtml) first. The HTML code contains an input type file control and a button. The file input control has an attribute named multiple as we need to support selection of multiple files.

<form method="post" enctype="multipart/form-data"> 
    <div class="row">
        <div class="col-md-12">
           <input type="file" id="fUpload" name="files" multiple class="form-control" />
        </div>
    </div>
    <div class="row">
        <div class="col-md-12" style="padding-top:10px;">
            <input type="button" id="btnUpload" value="Upload" />
        </div>
    </div>
</form>

Server Side Code

The jQuery script sends the anti-forgery token in a header called X-CSRF-TOKEN, configure the anti-forgery service to look for the X-CSRF-TOKEN header. Making Ajax request with ASP.NET Core Razor pages is bit different. I already covered this in Handle Ajax Requests in ASP.NET Core Razor Pages

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
}

Below is the code of Index Model. This class exposes a POST method named OnPostUpload which would be called from jQuery. This method stores the uploaded files in wwwroot\Upload path. To get the wwwroot folder path, inject IHostingEnvironment services in the class constructor and assign it to a variable.

The Upload method accepts a list of IFromFile object. ASP.NET Core added a new interface IFromFile, which represents a file sent with the HttpRequest. The rest of the code is self-explanatory.

public class IndexModel : PageModel
{
    private IHostingEnvironment _hostingEnvironment;
    public IndexModel(IHostingEnvironment hostingEnvironment)
    {
        _hostingEnvironment = hostingEnvironment;
    }
    public void OnGet()
    {
    }

    public ActionResult OnPostUpload(List<IFormFile> files)
    {
        if(files != null && files.Count > 0)
        {
            string folderName = "Upload";
            string webRootPath = _hostingEnvironment.WebRootPath;
            string newPath = Path.Combine(webRootPath, folderName);
            if(!Directory.Exists(newPath))
            {
                Directory.CreateDirectory(newPath);
            }
            foreach (IFormFile item in files)
            {
                if (item.Length > 0)
                {
                    string fileName = ContentDispositionHeaderValue.Parse(item.ContentDisposition).FileName.Trim('"');
                    string fullPath = Path.Combine(newPath, fileName);
                    using (var stream = new FileStream(fullPath, FileMode.Create))
                    {
                        item.CopyTo(stream);
                    }
                }
            }
            return this.Content("Success");
        }
        return this.Content("Fail");
    }
}

jQuery Code

The jQuery script uses FormData object to store multiple files and passes the same object to the POST method. Regarding FormData object, the official documentation says,

The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to “multipart/form-data”.

The script creates a new FormData object and loops through all the selected files for upload and appends it in FormData object.The jQuery ajax code does the following things,

  • Passes the anti-forgery token with Ajax request header, which gets validated at server. Antiforgery token generation and validation are automatically included in Razor Pages.
  • Passes the FormData object in data attribute.
  • Set contentType to false. This tells jQuery to not add Content-Type header to the request.
  • Set processData to false. This will stop jQuery to convert data value to a string.
$(document).ready(function () {
   $('#btnUpload').on('click', function () {
      var files = $('#fUpload').prop("files");
      var fdata = new FormData();
      for (var i = 0; i < files.length; i++)
      {
          fdata.append("files", files[i]);
      }
      if (files.length > 0) {
          $.ajax({
             type: "POST",
             url: "/Index?handler=Upload",
             beforeSend: function (xhr) {
                xhr.setRequestHeader("XSRF-TOKEN",
                   $('input:hidden[name="__RequestVerificationToken"]').val());
             },
             data: fdata,
             contentType: false,
             processData: false,
             success: function (response) {
               alert('File Uploaded Successfully.')
             }
          });
      }
      else {
          alert('Please select a file.')
      }
   })
});

That’s it. We are all set. Now when you run this application, you should see the following.

Uploading Multiple Files in ASP.NET Core Razor Pages

You can find the source code in the Github.

Thank you for reading. Keep visiting this blog and share this in your network. Please put your thoughts and feedback in the comments section.

2 thoughts on “Uploading Multiple Files in ASP.NET Core Razor Pages

Leave a Reply

Your email address will not be published. Required fields are marked *

twelve − 2 =