Introduction
In the previous article of this series AngularJS With ASP.NET MVC I have explained how to retrieve and display master details tabular data with AngularJS and ASP.NET MVC. Today I will show you Part 8 - How to upload files with AngularJS and ASP.NET MVC application.The file input type does not support 2 way binding, so we need to find an own solution for file uploads with AngularJS. Here In this example, I would like to how to upload files with AngularJS and ASP.NET MVC application.
Steps :
Step-1: Create table(s) into the database.
Open Database > Right Click on Table > Add New Table > Add Columns > Save > Enter table name > Ok.Step-2: Update Entity Data Model.
Go to Solution Explorer > Open your Entity Data Model (here "MyModel.edmx") > Right Click On Blank area for Get Context Menu > Update Model From Database... > A popup window will come (Entity Data Model Wizard) > Select Tables > Finish.Step-3: Add a folder for Save uploaded files.
Go to Solution Explorer > Right Click on the project > Add > New Folder > Enter Folder NameHere I have named the folder "UploadedFiles".
Step-4: Add new action into your controller (here in the Data Controller) for upload File and Save Data to the Database.
Here I have added "SaveFiles" Action into "DataController". Please write this following code[HttpPost]
public JsonResult SaveFiles(string description)
{
string Message, fileName, actualFileName;
Message = fileName = actualFileName = string.Empty;
bool flag = false;
if (Request.Files != null)
{
var file = Request.Files[0];
actualFileName = file.FileName;
fileName = Guid.NewGuid() + Path.GetExtension(file.FileName);
int size = file.ContentLength;
try
{
file.SaveAs(Path.Combine(Server.MapPath("~/UploadedFiles"), fileName));
UploadedFile f = new UploadedFile
{
FileName = actualFileName,
FilePath = fileName,
Description = description,
FileSize = size
};
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
dc.UploadedFiles.Add(f);
dc.SaveChanges();
Message = "File uploaded successfully";
flag = true;
}
}
catch (Exception)
{
Message = "File upload failed! Please try again";
}
}
return new JsonResult { Data = new { Message = Message, Status = flag } };
}
Step-5: Add a new js File for add a new AngularJS controller and a Factory
Go to Solution Explorer > Right Click on folder (where you want to saved your AngularJS controller files, here I have created a folder named "AngularController" under Scripts Folder) > Add > Select Javascript file > Enter name > Add.Write following code in this file.
angular.module('MyApp') // extending angular module from first part
.controller('Part8Controller', function ($scope, FileUploadService) {
// Variables
$scope.Message = "";
$scope.FileInvalidMessage = "";
$scope.SelectedFileForUpload = null;
$scope.FileDescription = "";
$scope.IsFormSubmitted = false;
$scope.IsFileValid = false;
$scope.IsFormValid = false;
//Form Validation
$scope.$watch("f1.$valid", function (isValid) {
$scope.IsFormValid = isValid;
});
// THIS IS REQUIRED AS File Control is not supported 2 way binding features of Angular
// ------------------------------------------------------------------------------------
//File Validation
$scope.ChechFileValid = function (file) {
var isValid = false;
if ($scope.SelectedFileForUpload != null) {
if ((file.type == 'image/png' || file.type == 'image/jpeg' || file.type == 'image/gif') && file.size <= (512 * 1024)) {
$scope.FileInvalidMessage = "";
isValid = true;
}
else {
$scope.FileInvalidMessage = "Selected file is Invalid. (only file type png, jpeg and gif and 512 kb size allowed)";
}
}
else {
$scope.FileInvalidMessage = "Image required!";
}
$scope.IsFileValid = isValid;
};
//File Select event
$scope.selectFileforUpload = function (file) {
$scope.SelectedFileForUpload = file[0];
}
//----------------------------------------------------------------------------------------
//Save File
$scope.SaveFile = function () {
$scope.IsFormSubmitted = true;
$scope.Message = "";
$scope.ChechFileValid($scope.SelectedFileForUpload);
if ($scope.IsFormValid && $scope.IsFileValid) {
FileUploadService.UploadFile($scope.SelectedFileForUpload, $scope.FileDescription).then(function (d) {
alert(d.Message);
ClearForm();
}, function (e) {
alert(e);
});
}
else {
$scope.Message = "All the fields are required.";
}
};
//Clear form
function ClearForm() {
$scope.FileDescription = "";
//as 2 way binding not support for File input Type so we have to clear in this way
//you can select based on your requirement
angular.forEach(angular.element("input[type='file']"), function (inputElem) {
angular.element(inputElem).val(null);
});
$scope.f1.$setPristine();
$scope.IsFormSubmitted = false;
}
})
.factory('FileUploadService', function ($http, $q) { // explained abour controller and service in part 2
var fac = {};
fac.UploadFile = function (file, description) {
var formData = new FormData();
formData.append("file", file);
//We can send more data to server using append
formData.append("description", description);
var defer = $q.defer();
$http.post("/Data/SaveFiles", formData,
{
withCredentials: true,
headers: { 'Content-Type': undefined },
transformRequest: angular.identity
})
.success(function (d) {
defer.resolve(d);
})
.error(function () {
defer.reject("File Upload Failed!");
});
return defer.promise;
}
return fac;
});
Step-6: Add new action into your controller (here in the HomeController) for Get the view for upload file & save Data.
Here I have added "Part8" Action into "Home" Controller. Please write this following codepublic ActionResult Part8() // Upload File with Data
{
return View();
}
Step-7: Add view for the Action & design.
Right Click on Action Method (here right click on Part8 action) > Add View... > Enter View Name > Select View Engine (Razor) > Add.Complete View
@{
ViewBag.Title = "Part8";
}
<h2>Part8 - Upload file using Angular JS</h2>
<div ng-controller="Part8Controller">
<form novalidate name="f1" ng-submit="SaveFile()">
<div style="color: red">{{Message}}</div>
<table>
<tr>
<td>Select File : </td>
<td>
<input type="file" name="file" accept="image/*" onchange="angular.element(this).scope().selectFileforUpload(this.files)" required />
<span class="error" ng-show="(f1.file.$dirty || IsFormSubmitted) && f1.file.$error.required">Image required!</span>
<span class="error">{{FileInvalidMessage}}</span>
</td>
</tr>
<tr>
<td>Description : </td>
<td>
<input type="text" name="uFileDescription" ng-model="FileDescription" class="{{(IsFormSubmitted?'ng-dirty' + (f1.uFileDescription.$invalid?' ng-invalid':''):'')}}" autofocus />
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Upload File" />
</td>
</tr>
</table>
</form>
</div>
@section Scripts{
<script src="~/Scripts/AngularController/Part8Controller.js"></script>
}