Donate

How To Send Or Upload A Form With Multiple Files Using HttpPostedFileBase Array, jQuery And Ajax In ASP.NET MVC

Good evening,

This blog post demonstrates on how to upload or send a form with multiple files using HttpPostedFileBase class which is a property of a model class using jQuery and ajax in ASP.NET MVC. Given a sample model, I have declared a HttpPostedFileBase array property which is responsible for handling multiple files.
public class clsWeeklyStatusReports
{
	  public Guid ID { get; set; }

	  public string DomainName { get; set; }
	  
	  public string EmployeeName { get; set; }

	  public DateTime SubmissionDate { get; set; }

	  public string SubmissionDateDisplay { get { return SubmissionDate.ToString("MM/dd/yyyy"); } }
	  
	  public string MimeType { get; set; }

	  public string FileName { get; set; }

	  public HttpPostedFileBase[] Files { get; set; }

	  public clsWeeklyStatusReportsGM()
	  {
		 ID = Guid.Empty;
		 DomainName = string.Empty;
		 EmployeeName = string.Empty;
		 MimeType = string.Empty;
		 FileName = string.Empty;
		 SubmissionDate = new DateTime();
	  }
}
In turn, that property will be bound to a File Upload control which is enabled to accept multiple files that is part of the form element such as this.
@using (Html.BeginForm("WeeklyStatus", "EmployeeDashboard", FormMethod.Post, new { id = "frmWeeklyStatus", enctype = "multipart/form-data" }))
{
	 @Html.AntiForgeryToken()

	 <div id="divWeeklyStatusFileUpload" class="row">
		<div class="col-md-4">
		   @Html.Label("Weekly Status Report", htmlAttributes: new { @class = "control-label" })
		</div>
		<div class="col-md-4">
		   @Html.TextBoxFor(model => model.Files, "", new { @type = "file", @multiple = "multiple" })
		</div>
		<div class="col-md-4">
		   <button id="btnUpload" type="submit" name="submit" value="Send" class="btn btn-default" style="width:140px;">
			  <span class="glyphicon glyphicon-upload"></span> Upload File(s)
		   </button>
		</div>
	 </div>
}
The controller action as observed will receive a clsWeeklyStatusReports object which then retrieves the files uploaded via the HttpPostedFileBase Files property.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveWeeklyStatusReport(clsWeeklyStatusReports model)
{
     var files = model.Files;
	 //more codes here...
        
	 return Json(new { Success = true, StatusMessage = "" }, JsonRequestBehavior.AllowGet);
}
The JavaScript function will serialize the form data and post to the MVC controller action. However, this method does not work as expected since we are passing a model object instead of HttpPostedFile object.
function ValidateFileUpload() {
	 $('#btnUpload').click(function (e) {
		e.preventDefault();
		let numFiles = $('input:file')[0].files.length;		
		let formData =  $("#frmWeeklyStatus").serialize();
		
		if (parseInt(numFiles) < 1) {
		   AlertDialog('File Upload Error', 'File(s) is required for weekly status report!', 300, 150);
		   return false;
		}

		$.ajax({
		   url: urlSaveWeeklyStatusReport,
		   type: "POST",
		   data: formData,
		   processData: false,
		   contentType: false,
		   success: function (result) {
			  AlertDialog('Save Weekly Reports', 'Saving of weekly status reports successful!', 300, 150);
			  $('#tblWeeklyStatusReport').bootstrapTable('refresh');
		   },
		   error: function (result) {
			  AlertDialog('Save Weekly Reports Error', 'Error while saving weekly status reports records!', 400, 150);
		   }
		});
	 });
}
I did some research on how to send multiple files which led me to a fix FormData() function in JavaScript. However this statement 'let formData = new FormData($("#frmWeeklyStatusReport"));' will cause an issue specifically "Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'."
function ValidateFileUpload() {
	 $('#btnUpload').click(function (e) {
		e.preventDefault();
		let numFiles = $('input:file')[0].files.length;		
		let formData = new FormData($("#frmWeeklyStatus"));
		
		if (parseInt(numFiles) < 1) {
		   AlertDialog('File Upload Error', 'File(s) is required for weekly status report!', 300, 150);
		   return false;
		}

		$.ajax({
		   url: urlSaveWeeklyStatusReport,
		   type: "POST",
		   data: formData,
		   processData: false,
		   contentType: false,
		   success: function (result) {
			  AlertDialog('Save Weekly Reports', 'Saving of weekly status reports successful!', 300, 150);
			  $('#tblWeeklyStatusReport').bootstrapTable('refresh');
		   },
		   error: function (result) {
			  AlertDialog('Save Weekly Reports Error', 'Error while saving weekly status reports records!', 400, 150);
		   }
		});
	 });
}
The final function that solves the issue "Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'." is to replace the let formData = new FormData($("#frmWeeklyStatusReport")); snippet to use document.getElementById() in retrieving the form object.
function ValidateFileUpload() {
	 $('#btnUpload').click(function (e) {
		e.preventDefault();
		let numFiles = $('input:file')[0].files.length;		
		let formData = new FormData(document.getElementById("frmWeeklyStatus"));
		
		if (parseInt(numFiles) < 1) {
		   AlertDialog('File Upload Error', 'File(s) is required for weekly status report!', 300, 150);
		   return false;
		}

		$.ajax({
		   url: urlSaveWeeklyStatusReport,
		   type: "POST",
		   data: formData,
		   processData: false,
		   contentType: false,
		   success: function (result) {
			  AlertDialog('Save Weekly Reports', 'Saving of weekly status reports successful!', 300, 150);
			  $('#tblWeeklyStatusReport').bootstrapTable('refresh');
		   },
		   error: function (result) {
			  AlertDialog('Save Weekly Reports Error', 'Error while saving weekly status reports records!', 400, 150);
		   }
		});
	 });
}
Screenshot
How To Send Or Upload A Form With Multiple Files Using HttpPostedFileBase Array, jQuery And Ajax In ASP.NET MVC

Comments

Donate

Popular Posts From This Blog

WPF CRUD Application Using DataGrid, MVVM Pattern, Entity Framework, And C#.NET

TypeScript Error Or Bug: The term 'tsc' is not recognized as the name of a cmdlet, function, script file, or operable program.

Invalid nested tag div found, expected closing tag input