Uploading File using Ajax in Asp.Net Core

64,829

Solution 1

It is well explained here:

Browser Side Code:

HTML

<form id="form" name="form" action="/uploader" enctype="multipart/form-data" method="post">
  <div class="buttons">
    <div class="upload-button">
      <div class="label">Click me!</div>
      <input id="files" name="files" type="file" size="1" multiple onchange="uploadFiles('files');" />
    </div>
  </div>
</form>

JavaScript

function uploadFiles(inputId) {
  var input = document.getElementById(inputId);
  var files = input.files;
  var formData = new FormData();

  for (var i = 0; i != files.length; i++) {
    formData.append("files", files[i]);
  }

  $.ajax(
    {
      url: "/uploader",
      data: formData,
      processData: false,
      contentType: false,
      type: "POST",
      success: function (data) {
        alert("Files Uploaded!");
      }
    }
  );
}

Server Side Code:

[HttpPost]
public async Task<IActionResult> Index(IList<IFormFile> files)
{
  foreach (IFormFile source in files)
  {
    string filename = ContentDispositionHeaderValue.Parse(source.ContentDisposition).FileName.Trim('"');

    filename = this.EnsureCorrectFilename(filename);

    using (FileStream output = System.IO.File.Create(this.GetPathAndFilename(filename)))
      await source.CopyToAsync(output);
  }

  return this.View();
}

private string EnsureCorrectFilename(string filename)
{
  if (filename.Contains("\\"))
    filename = filename.Substring(filename.LastIndexOf("\\") + 1);

  return filename;
}

private string GetPathAndFilename(string filename)
{
  return this.hostingEnvironment.WebRootPath + "\\uploads\\" + filename;
}

Solution 2

Here's a simple way to post a file to your controller's action.

View:

var formData = new FormData();
formData.append('file', $('#myfile')[0].files[0]); // myFile is the input type="file" control

var _url = '@Url.Action("UploadFile", "MyController")';

$.ajax({
    url: _url,
    type: 'POST',
    data: formData,
    processData: false,  // tell jQuery not to process the data
    contentType: false,  // tell jQuery not to set contentType
    success: function (result) {
    },
    error: function (jqXHR) {
    },
    complete: function (jqXHR, status) {
    }
});

Controller:

[HttpPost]
public ActionResult UploadFile(IFormFile file)
{
    List<string> errors = new List<string>(); // added this just to return something

    if (file != null)
    {
        // do something
    }

    return Json(errors, JsonRequestBehavior.AllowGet);   
}

Solution 3

You just need to specify file input "name" attribute (same as variable name in ASP.NET controller). HTML:

<input type="file" name="thefile" />

C#:

public ActionResult UploadFile(IFormFile thefile) { }

For AJAX request you need to specify appropriate name in FormData object.

Solution 4

Fully working example with (.Net Core). Some portion of the answer adopted from the above answers with fixing the compilation errors.

Assuming you want to upload files then you'll submit the form with the uploaded files.

Register.cshtml

@using UploadFileAjaxPostWebApp.Models.Account

@model RegisterModel

@using (Html.BeginForm("Register", "Account", FormMethod.Post))
{
  <div>
    <label>First Name </label>
    <input type="text" name="FirstName" value="John" />
  </div>
  <div>
    <label>Second Name </label>
    <input type="text" name="SecondName" value="Smith" />
  </div>
  <div>
    <label>Resume</label>
    <input type="file" id="fileUpload1" onchange="uploadFiles('fileUpload1');" />
    <input type="hidden" id="ResumeFileName" name="ResumeFileName" value="@Model.ResumeFileName" />
  </div>

  <div>
    <input type="submit" value="Submit" />
  </div>
}

<script type="text/javascript">

function uploadFiles(inputId) {
    var input = document.getElementById(inputId);
    var files = input.files;
    var formData = new FormData();

    for (var i = 0; i !== files.length; i++) {
        formData.append("files", files[i]);
    }

    $.ajax(
        {
            url: "/account/uploadfiles",
            data: formData,
            processData: false,
            contentType: false,
            type: "POST",
            success: function (data) {
                // Set the property of the Model.
                $("#ResumeFileName").val(data.fileName);
                alert("Files Uploaded! " + data.fileName);
            }
        }
    );
}
</script>

Account Controller:

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using UploadFileAjaxPostWebApp.Models.Account;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Net.Http.Headers;

namespace UploadFileAjaxPostWebApp.Controllers
{
  public class AccountController : Controller
  {
    private readonly IWebHostEnvironment _hostEnvironment;

    public AccountController(IWebHostEnvironment hostEnvironment)
    {
        _hostEnvironment = hostEnvironment;
    }

    public IActionResult Register()
    {
        RegisterModel model = new RegisterModel();

        return View(model);
    }

    [HttpPost]
    public IActionResult Register(RegisterModel model)
    {
        // Handle your post action ....
        return View(model);
    }

    [HttpPost]
    public async Task<ActionResult> UploadFiles(IList<IFormFile> files)
    {
        string fileName = null;

        foreach (IFormFile source in files)
        {
            // Get original file name to get the extension from it.
            string orgFileName = ContentDispositionHeaderValue.Parse(source.ContentDisposition).FileName.Value;

            // Create a new file name to avoid existing files on the server with the same names.
            fileName = DateTime.Now.ToFileTime() + Path.GetExtension(orgFileName);

            string fullPath = GetFullPathOfFile(fileName);

            // Create the directory.
            Directory.CreateDirectory(Directory.GetParent(fullPath).FullName);

            // Save the file to the server.
            await using FileStream output = System.IO.File.Create(fullPath);
            await source.CopyToAsync(output);
        }

        var response = new { FileName = fileName };

        return Ok(response);
    }

    private string GetFullPathOfFile(string fileName)
    {
        return $"{_hostEnvironment.WebRootPath}\\uploads\\{fileName}";
    }
 }
}

RegisterModel class

namespace UploadFileAjaxPostWebApp.Models.Account
{
  public class RegisterModel
  {
    public string FirstName { get; set; }

    public string SecondName { get; set; }

    public string ResumeFileName { get; set; }
  }
}
Share:
64,829
jsonGPPD
Author by

jsonGPPD

Updated on June 30, 2021

Comments

  • jsonGPPD
    jsonGPPD almost 3 years

    Good day everyone,

    I'm trying to upload file using ajax from client side to server side (asp.net core) controller but I'm having a null value.

    Here's my html and javascript codes:

    <input type="file" id="myfile" class="required" />
    <button type="button" class="btn btn-info" onclick="uploadcsvfile()">
    
    <script>
        function uploadcsvfile() {
           var myfile= document.getElementById("myfile");
           var formData = new FormData();
    
           if (myfile.files.length > 0) {
               for (var i = 0; i < myfile.files.length; i++) {
                   formData.append('file-' + i, myfile.files[i]);
               }
           }
    
           $.ajax({
               url: "/MyController/UploadFile/",
               type: "POST",
               dataType: "json",
               data: formData,
               contentType: false,
               processData: false,
               success: function(data){
    
               },
               error: function (data) {
    
               }
            })
        }
    </script>
    

    Here's my controller that uses IFormFile

    public async Task<JsonResult> UploadFile(IFormFile formData)
    {
          // do something here
    }
    

    Thank you in advance!