Software Prerequisites
To follow this tutorial, ensure you have the following tools installed on your development machine.
Development IDE
Runtime Framework
Project Directory Structure
The uploaded files will be stored in a folder named Uploads located within the wwwroot folder.
The screenshot below shows the Solution Explorer.
Controller Logic
IWebHostEnvironment Dependency injection
The Constructor is injected access the IWebHostEnvironment service.
Note: The IWebHostEnvironment service is the standard way to retrieve the physical path of the wwwroot folder.
private readonly IWebHostEnvironment _env;
//Dependency Injection
public HomeController(IWebHostEnvironment env)
{
_env = env;
}
The Controller manages the file upload process through two primary action methods:
Handling GET Requests
This method is used to load the initial page. It simply returns the Index view to the browser.
public IActionResult Index()
{
return View();
}
Handling POST Requests
This method processes the actual file upload. It is decorated with the HttpPost attribute and accepts a collection of files via the IFormFile interface.
Note: The name of the IFormFile parameter and the name of FormData must be exactly the same (case-sensitive , otherwise the IFormFile parameter will be NULL.
A loop is executed over the IFormFile collection and inside the loop, the name of the file is determined and then the path of the Uploads folder is generated which is located inside the wwwroot folder.
Then using Stream class, the file is saved in the Uploads folder.
Finally, the names of the uploaded Files are returned to the
jQuery AJAX function.
[HttpPost]
public async Task<IActionResult> Uploads(List<IFormFile>postedFiles)
{
string message = "";
//Loop and save each file.
foreach (IFormFile postedFile in postedFiles)
{
//Extract the File Name.
string fileName = Path.GetFileName(postedFile.FileName);
//Generate the Path where File will be saved.
string path = Path.Combine(_env.WebRootPath, "Uploads", fileName);
//Save the File.
using Stream stream = System.IO.File.Create(path);
await postedFile.CopyToAsync(stream);
//Generate message for displaying File Names.
message += string.Format("<b>{0}</b>uploaded.<br />", fileName);
}
return Content(message);
}
View (HTML)
In this section, we define the HTML structure and the
jQuery AJAX logic required to send files to the server asynchronously.
By using
AJAX, we can upload files without a full-page refresh.
HTML Markup
The following structure uses standard HTML consisting of file input for selecting file, a button that will trigger the file upload process and a span that will display the success message.
Note: Ensure the file input has the attribute multiple to allow batch selection.
<!-- File selection input with multiple attribute-->
<span>Select File:</span>
<input type="file" id="postedFile" multiple="multiple"/>
<!-- Trigger button -->
<input type="button" id="btnUpload" value="Upload" />
<br />
<br />
<!-- Success Message label -->
<span id="lblMessage" style="color:green"></span>
jQuery implementation
Within the document.ready event handler, an onclick event handler is assigned to the Upload button.
First, the files are retrieved from the HTML file input and then using a for loop, each file is appended to the FormData object named postedFiles.
Once the data is prepared, an
AJAX request sends the files to the Controller.
Finally, a success message is displayed within an HTML SPAN element.
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script>
$(function(){
$("#btnUpload").click(function(){
//Select the Files
var files = $('#postedFile').prop("files");
//Create FormData object.
var formData = new FormData();
//Loop through selected files and append to FormData
for (var i = 0;i <files.length;i++) {
formData.append("postedFiles", files[i]);
}
//The AJAX implementation
$.ajax({
url:'/Home/Upload',//URL to the Controller.
type:'POST',
data:formData,//The FormData object.
processData:false,//Prevents FormData string conversion.
contentType:false,//Disables default Content Type.
success:function (response) {
//Display the success message.
$("#lblMessage").html(response);
},
error:function () {
alert("Upload failed.");
}
});
});
});
</script>
Logic Breakdown
FormData Object
This is a built-in browser object that allows us to send key/value pairs to the server via
AJAX.
The Loop
Each file is added to the FormData object using the for loop.
processData & contentType set to false
If left as true, jQuery will attempt to format your file data incorrectly, causing the server to reject the file upload request.
Screenshot
Downloads