Saturday, August 10, 2019

How to upload files with AngularJS and ASP.NET MVC application

Step-1: Create table(s) into the database.

Open Database > Right Click on Table > Add New Table > Add Columns > Save > Enter table name > Ok. 
In this example, I have used two tables as below

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 Name 
Here 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 

  1. [HttpPost]
  2. public JsonResult SaveFiles(string description)
  3. {
  4. string Message, fileName, actualFileName;
  5. Message = fileName = actualFileName = string.Empty;
  6. bool flag = false;
  7. if (Request.Files != null)
  8. {
  9. var file = Request.Files[0];
  10. actualFileName = file.FileName;
  11. fileName = Guid.NewGuid() + Path.GetExtension(file.FileName);
  12. int size = file.ContentLength;
  13.  
  14. try
  15. {
  16. file.SaveAs(Path.Combine(Server.MapPath("~/UploadedFiles"), fileName));
  17.  
  18. UploadedFile f = new UploadedFile
  19. {
  20. FileName = actualFileName,
  21. FilePath = fileName,
  22. Description = description,
  23. FileSize = size
  24. };
  25. using (MyDatabaseEntities dc = new MyDatabaseEntities())
  26. {
  27. dc.UploadedFiles.Add(f);
  28. dc.SaveChanges();
  29. Message = "File uploaded successfully";
  30. flag = true;
  31. }
  32. }
  33. catch (Exception)
  34. {
  35. Message = "File upload failed! Please try again";
  36. }
  37.  
  38. }
  39. return new JsonResult { Data = new { Message = Message, Status = flag } };
  40. }

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. 

  1. angular.module('MyApp') // extending angular module from first part
  2. .controller('Part8Controller', function ($scope, FileUploadService) {
  3. // Variables
  4. $scope.Message = "";
  5. $scope.FileInvalidMessage = "";
  6. $scope.SelectedFileForUpload = null;
  7. $scope.FileDescription = "";
  8. $scope.IsFormSubmitted = false;
  9. $scope.IsFileValid = false;
  10. $scope.IsFormValid = false;
  11.  
  12. //Form Validation
  13. $scope.$watch("f1.$valid", function (isValid) {
  14. $scope.IsFormValid = isValid;
  15. });
  16.  
  17.  
  18. // THIS IS REQUIRED AS File Control is not supported 2 way binding features of Angular
  19. // ------------------------------------------------------------------------------------
  20. //File Validation
  21. $scope.ChechFileValid = function (file) {
  22. var isValid = false;
  23. if ($scope.SelectedFileForUpload != null) {
  24. if ((file.type == 'image/png' || file.type == 'image/jpeg' || file.type == 'image/gif') && file.size <= (512 * 1024)) {
  25. $scope.FileInvalidMessage = "";
  26. isValid = true;
  27. }
  28. else {
  29. $scope.FileInvalidMessage = "Selected file is Invalid. (only file type png, jpeg and gif and 512 kb size allowed)";
  30. }
  31. }
  32. else {
  33. $scope.FileInvalidMessage = "Image required!";
  34. }
  35. $scope.IsFileValid = isValid;
  36. };
  37. //File Select event
  38. $scope.selectFileforUpload = function (file) {
  39. $scope.SelectedFileForUpload = file[0];
  40. }
  41. //----------------------------------------------------------------------------------------
  42.  
  43. //Save File
  44. $scope.SaveFile = function () {
  45. $scope.IsFormSubmitted = true;
  46. $scope.Message = "";
  47. $scope.ChechFileValid($scope.SelectedFileForUpload);
  48. if ($scope.IsFormValid && $scope.IsFileValid) {
  49. FileUploadService.UploadFile($scope.SelectedFileForUpload, $scope.FileDescription).then(function (d) {
  50. alert(d.Message);
  51. ClearForm();
  52. }, function (e) {
  53. alert(e);
  54. });
  55. }
  56. else {
  57. $scope.Message = "All the fields are required.";
  58. }
  59. };
  60. //Clear form
  61. function ClearForm() {
  62. $scope.FileDescription = "";
  63. //as 2 way binding not support for File input Type so we have to clear in this way
  64. //you can select based on your requirement
  65. angular.forEach(angular.element("input[type='file']"), function (inputElem) {
  66. angular.element(inputElem).val(null);
  67. });
  68.  
  69. $scope.f1.$setPristine();
  70. $scope.IsFormSubmitted = false;
  71. }
  72.  
  73. })
  74. .factory('FileUploadService', function ($http, $q) { // explained abour controller and service in part 2
  75.  
  76. var fac = {};
  77. fac.UploadFile = function (file, description) {
  78. var formData = new FormData();
  79. formData.append("file", file);
  80. //We can send more data to server using append
  81. formData.append("description", description);
  82.  
  83. var defer = $q.defer();
  84. $http.post("/Data/SaveFiles", formData,
  85. {
  86. withCredentials: true,
  87. headers: { 'Content-Type': undefined },
  88. transformRequest: angular.identity
  89. })
  90. .success(function (d) {
  91. defer.resolve(d);
  92. })
  93. .error(function () {
  94. defer.reject("File Upload Failed!");
  95. });
  96.  
  97. return defer.promise;
  98.  
  99. }
  100. return fac;
  101.  
  102. });

Here I have created an angular controller named "Part8Controller" and a Factory named "FileUploadService" with $http injected service. I have explained a little about AngularJS controller here , about Factory here and about $http here.

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 code 

  1. public ActionResult Part8() // Upload File with Data
  2. {
  3. return View();
  4. }

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 
  1. @{
  2. ViewBag.Title = "Part8";
  3. }
  4.  
  5. <h2>Part8 - Upload file using Angular JS</h2>
  6. <div ng-controller="Part8Controller">
  7. <form novalidate name="f1" ng-submit="SaveFile()">
  8. <div style="color: red">{{Message}}</div>
  9. <table>
  10. <tr>
  11. <td>Select File : </td>
  12. <td>
  13. <input type="file" name="file" accept="image/*" onchange="angular.element(this).scope().selectFileforUpload(this.files)" required />
  14. <span class="error" ng-show="(f1.file.$dirty || IsFormSubmitted) && f1.file.$error.required">Image required!</span>
  15. <span class="error">{{FileInvalidMessage}}</span>
  16. </td>
  17. </tr>
  18. <tr>
  19. <td>Description : </td>
  20. <td>
  21. <input type="text" name="uFileDescription" ng-model="FileDescription" class="{{(IsFormSubmitted?'ng-dirty' + (f1.uFileDescription.$invalid?' ng-invalid':''):'')}}" autofocus />
  22. </td>
  23. </tr>
  24. <tr>
  25. <td></td>
  26. <td>
  27. <input type="submit" value="Upload File" />
  28. </td>
  29. </tr>
  30. </table>
  31.  
  32. </form>
  33. </div>
  34.  
  35. @section Scripts{
  36. <script src="~/Scripts/AngularController/Part8Controller.js"></script>
  37. }

Step-8: Run Application.

No comments:

Post a Comment

How to register multiple implementations of the same interface in Asp.Net Core?

 Problem: I have services that are derived from the same interface. public interface IService { } public class ServiceA : IService { ...