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> }