CRUD Using MVC Web API And AngularJS

In this demo application our main concern will be on AngularJS data-binding and routing. I also used Entity Framework Code First approach for database operation.

Functionality present in this application:

  1. Data Binding using AngularJS
  2. Client side routing using Angular Routing
  3. Cascading Dropdown using AngularJS
  4. Conditional formatting using AngularJS
  5. Select, Insert, Update and Delete record in SQL Server database.

Let’s start step by step so that we can achieve our objective at the end of this article. After completing this demo our application should look like this:

  1. Employee List page:

    table

  2. Employee Page for Creating and Editing a record.

    Edit a record

  3. Employee Delete Confirmation page with details:

    Employee Delete Confirmation

To achieve the above, follow the steps given below:

  1. Create a new ASP.NET MVC Empty Web Application.

  2. Add the following package in your application:

    1. AngularJS.Core
    2. AngularJS.Route
    3. Bootstrap
    4. EntityFramework

  3. Create a Model named Employee in Models folder and replace the code with the following:
    1. public class Employee  
    2. {  
    3.     public int EmployeeId  
    4.     {  
    5.         get;  
    6.         set;  
    7.     }  
    8.     [Required]  
    9.     [StringLength(20)]  
    10.     public string FirstName  
    11.     {  
    12.         get;  
    13.         set;  
    14.     }  
    15.     [Required]  
    16.     [StringLength(20)]  
    17.     public string LastName  
    18.     {  
    19.         get;  
    20.         set;  
    21.     }  
    22.     [Required]  
    23.     [StringLength(100)]  
    24.     public string Description  
    25.     {  
    26.         get;  
    27.         set;  
    28.     }  
    29.     public float Salary  
    30.     {  
    31.         get;  
    32.         set;  
    33.     }  
    34.     [Required]  
    35.     [StringLength(50)]  
    36.     public string Country  
    37.     {  
    38.         get;  
    39.         set;  
    40.     }  
    41.     [Required]  
    42.     [StringLength(50)]  
    43.     public string State  
    44.     {  
    45.         get;  
    46.         set;  
    47.     }  
    48.     public DateTime DateofBirth  
    49.     {  
    50.         get;  
    51.         set;  
    52.     }  
    53.     public bool IsActive  
    54.     {  
    55.         get;  
    56.         set;  
    57.     }  
    58. }  
    59. public class EmployeeDbContext: DbContext  
    60. {  
    61.     public EmployeeDbContext(): base()  
    62.     {  
    63.         Database.SetInitializer < EmployeeDbContext > (newEmployeeDbContextInitializer());  
    64.     }  
    65.     public DbSet < Employee > Employees  
    66.     {  
    67.         get;  
    68.         set;  
    69.     }  
    70. }  
    71. public class EmployeeDbContextInitializer: DropCreateDatabaseIfModelChanges < EmployeeDbContext >  
    72. {  
    73.     protected override void Seed(EmployeeDbContext context)  
    74.     {  
    75.         var list = new List < Employee >  
    76.         {  
    77.             new Employee  
    78.             {  
    79.                 FirstName = "Rohit", LastName = "Mane", Description = "Rohit Mane", DateofBirth = DateTime.Now.AddYears(-24), Country = "IN", State = "MH", Salary = 99999, IsActive = true  
    80.             },  
    81.             new Employee  
    82.             {  
    83.                 FirstName = "Shankar", LastName = "Kanase", Description = "Rahul Singh", DateofBirth = DateTime.Now.AddYears(-23), Country = "IN", State = "MH", Salary = 49999.28 f, IsActive = true  
    84.             }  
    85.         };  
    86.         list.ForEach(m =>  
    87.         {  
    88.             context.Employees.Add(m);  
    89.         });  
    90.         context.SaveChanges();  
    91.         base.Seed(context);  
    92.     }  
    93. }  
  4. Add a connection string with same name of EmployeeDbContext in web.config:
    1. <connectionStrings>  
    2.    <add name="EmployeeDbContext" connectionString="Data Source=(local);Initial Catalog=EmpDb;Integrated Security=true;" providerName="System.Data.SqlClient"/>  
    3. </connectionStrings>  
  5. Now create a Employee API controller to perform crud in database:
    1. public class EmployeeController: ApiController  
    2. {  
    3.     EmployeeDbContext db = new EmployeeDbContext();  
    4.     // GET api/employee  
    5.     [ActionName("get"), HttpGet]  
    6.     public IEnumerable < Employee > Emps()  
    7.     {  
    8.         return db.Employees.ToList();  
    9.     }  
    10.     // GET api/employee/5  
    11.     public Employee Get(int id)  
    12.     {  
    13.          return db.Employees.Find(id);  
    14.     }  
    15.     // POST api/employee  
    16.     public HttpResponseMessage Post(Employee model)  
    17.     {  
    18.         if (ModelState.IsValid)  
    19.         {  
    20.             db.Employees.Add(model);  
    21.             db.SaveChanges();  
    22.             HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, model);  
    23.             return response;  
    24.         }  
    25.         else  
    26.         {  
    27.             return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);  
    28.         }  
    29.     }  
    30.     // PUT api/employee/5  
    31.     public HttpResponseMessage Put(Employee model)  
    32.     {  
    33.         if (ModelState.IsValid)  
    34.         {  
    35.             db.Entry(model).State = System.Data.Entity.EntityState.Modified;  
    36.             db.SaveChanges();  
    37.             HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, model);  
    38.             return response;  
    39.         }  
    40.         else  
    41.         {  
    42.             return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);  
    43.         }  
    44.     }  
    45.     // DELETE api/employee/5  
    46.     public HttpResponseMessage Delete(int id)  
    47.     {  
    48.         Employee emp = db.Employees.Find(id);  
    49.         if (emp == null)  
    50.         {  
    51.             return Request.CreateResponse(HttpStatusCode.NotFound);  
    52.         }  
    53.         db.Employees.Remove(emp);  
    54.         db.SaveChanges();  
    55.         return Request.CreateResponse(HttpStatusCode.OK, emp);  
    56.     }  
  6. Also create a Country controller to retrieve country and its states from server side in order to implement cascading dropdown list:
    1. public class CountryController: ApiController  
    2. {  
    3.     // GET api/country  
    4.     public IEnumerable < System.Web.Mvc.SelectListItem > Get()  
    5.     {  
    6.         List < System.Web.Mvc.SelectListItem > countries = newList < System.Web.Mvc.SelectListItem >  
    7.         {  
    8.             new System.Web.Mvc.SelectListItem  
    9.             {  
    10.                 Text = "India", Value = "IN"  
    11.             },  
    12.             new System.Web.Mvc.SelectListItem  
    13.             {  
    14.                 Text = "United States", Value = "US"  
    15.             },  
    16.             new System.Web.Mvc.SelectListItem  
    17.             {  
    18.                 Text = "United Kingdom", Value = "UK"  
    19.             },  
    20.             new System.Web.Mvc.SelectListItem  
    21.             {  
    22.                 Text = "Australlia", Value = "CA"  
    23.             }  
    24.         };  
    25.         return countries;  
    26.     }  
    27.     // GET api/country/5  
    28.     public IEnumerable < System.Web.Mvc.SelectListItem > Get(string id)  
    29.     {  
    30.         List < System.Web.Mvc.SelectListItem > states = newList < System.Web.Mvc.SelectListItem > ();  
    31.         switch (id)  
    32.         {  
    33.             case "IN":  
    34.                 states.Add(new System.Web.Mvc.SelectListItem  
    35.                 {  
    36.                     Text = "Maharashtra, Value = "  
    37.                     MH " });  
    38.                     states.Add(new System.Web.Mvc.SelectListItem  
    39.                     {  
    40.                         Text = "Madhya Pradesh", Value = "MP"  
    41.                     });  
    42.                     states.Add(new System.Web.Mvc.SelectListItem  
    43.                     {  
    44.                         Text = "Delhi", Value = "DL"  
    45.                     });  
    46.                     states.Add(new System.Web.Mvc.SelectListItem  
    47.                     {  
    48.                         Text = "Kanpur", Value = "KN"  
    49.                     });  
    50.                     break;  
    51.                     case "US":  
    52.                         states.Add(new System.Web.Mvc.SelectListItem  
    53.                         {  
    54.                             Text = "California", Value = "CA"  
    55.                         });  
    56.                         states.Add(new System.Web.Mvc.SelectListItem  
    57.                         {  
    58.                             Text = "Newyork", Value = "NY"  
    59.                         });  
    60.                         break;  
    61.                     case "UK":  
    62.                         states.Add(new System.Web.Mvc.SelectListItem  
    63.                         {  
    64.                             Text = "London", Value = "LN"  
    65.                         });  
    66.                         states.Add(new System.Web.Mvc.SelectListItem  
    67.                         {  
    68.                             Text = "Paris", Value = "PR"  
    69.                         });  
    70.                         break;  
    71.                    case "CA":  
    72.                         states.Add(new System.Web.Mvc.SelectListItem  
    73.                         {  
    74.                             Text = "Sydney", Value = "SD"  
    75.                         });  
    76.                         states.Add(new System.Web.Mvc.SelectListItem  
    77.                         {  
    78.                             Text = "Melbourne", Value = "MB"  
    79.                         });  
    80.                         break;  
    81.                 }  
    82.                 return states;  
    83.             }  
    84.         }  
  7. Now create a Home controller and add an Index view and reference some CSS and JavaScript files of AngularJS and bootstrap to create a view and partial views:
    1. public class HomeController: Controller  
    2. {  
    3.     public ActionResult Index()  
    4.     {  
    5.         return View();  
    6.     }  
    7. }  
  8. Index view with JS and CSS references:
    1. @{  
    2.     Layout = null;  
    3. }  
    4.   
    5. <!DOCTYPE html>  
    6. <html ng-app="EmpApp">  
    7.     <head>  
    8.         <meta name="viewport" content="width=device-width" />  
    9.         <title>Index</title>  
    10.         <link href="@Url.Content("~/Content/bootstrap.min.css")" rel="stylesheet"type="text/css" />  
    11.         <script src="@Url.Content("~/Scripts/angular.min.js")" type="text/javascript"></script>  
    12.         <script src="@Url.Content("~/Scripts/angular-route.js")"type="text/javascript"></script>  
    13.         <script src="@Url.Content("~/Scripts/app/app.js")" type="text/javascript"></script>  
    14.         <script src="@Url.Content("~/Scripts/app/controller.js")"type="text/javascript"></script>  
    15.     </head>  
    16.     <body>  
    17.         <div class="main container" ng-view></div>  
    18.     </body>  
    19. </html>  
    I have highlighted ng-app and ng-view attribute. This is for initializing module under app and rendering of partial views inside ng-view.

  9. Now create an app.js file for configuration of route and controllers. The code of app.js is given below:
    1. var EmpApp = angular.module('EmpApp', ['ngRoute''EmpControllers']);  
    2. EmpApp.config(['$routeProvider', function($routeProvider)  
    3. {  
    4.     $routeProvider.when('/list',  
    5.     {  
    6.         templateUrl: 'Employee/list.html',  
    7.         controller: 'ListController'  
    8.     }).  
    9.     when('/create',  
    10.     {  
    11.         templateUrl: 'Employee/edit.html',  
    12.         controller: 'EditController'  
    13.     }).  
    14.     when('/edit/:id',  
    15.     {  
    16.         templateUrl: 'Employee/edit.html',  
    17.         controller: 'EditController'  
    18.     }).  
    19.     when('/delete/:id',  
    20.     {  
    21.         templateUrl: 'Employee/delete.html',  
    22.         controller: 'DeleteController'  
    23.     }).  
    24.     otherwise(  
    25.     {  
    26.         redirectTo: '/list'  
    27.     });  
    28. }]);  
  10. Now add a folder named Employee under root directory of an application and following three views (html files) list.html, edit.html and delete.html.

    1. List.html
      1. <div>  
      2.     <a href="#/create" class="btn">Create</a>  
      3. </div>  
      4. <div class="table-responsive">  
      5.     <table class="table table-striped table-bordered">  
      6.         <tr>  
      7.             <th>Employee Id</th>  
      8.             <th>First Name</th>  
      9.             <th>Last Name</th>  
      10.             <th>Description</th>  
      11.             <th>Salary</th>  
      12.             <th>Country</th>  
      13.             <th>State</th>  
      14.             <th>Date of Birth</th>  
      15.             <th>Is Active</th>  
      16.             <th></th>  
      17.             <th></th>  
      18.         </tr>  
      19.         <tr ng-repeat="item in employees">  
      20.             <td>{{ item.EmployeeId }}</td>  
      21.             <td>{{ item.FirstName }}</td>  
      22.             <td>{{ item.LastName }}</td>  
      23.             <td>{{ item.Description }}</td>  
      24.             <td>{{ item.Salary | number: 2 }}</td>  
      25.             <td>{{ item.Country }}</td>  
      26.             <td>{{ item.State }}</td>  
      27.             <td>{{ item.DateofBirth | date }}</td>  
      28.             <td>  
      29.                 <span class="label" ng-class="{true:'label-success', false:'label-danger', '':'hidden'}[item.IsActive]">  
      30.                 {{ item.IsActive ? 'Active' : 'In Active' }}</span>  
      31.             </td>  
      32.             <td>  
      33.                 <a href="#/edit/{{item.EmployeeId}}" class="glyphicon glyphicon-edit"></a>  
      34.             </td>  
      35.             <td>  
      36.                 <a href="#/delete/{{item.EmployeeId}}" class="glyphicon glyphicon-trash"></a>  
      37.             </td>  
      38.         </tr>  
      39.     </table>  
      40. </div>  
    2. Edit.html
      1. <h3>  
      2. {{ title }}</h3>  
      3. <hr />  
      4. <form role="form" style="max-width: 500px;">  
      5.     <strong class="error">{{ error }}</strong>  
      6.     <div class="form-group">  
      7.         <label for="firstname">  
      8.         First Name</label>  
      9.         <input type="text" class="form-control" id="firstname" ng-model="firstname" />  
      10.     </div>  
      11.     <div class="form-group">  
      12.         <label for="lastname">  
      13.         Last Name:</label>  
      14.         <input type="text" class="form-control" id="lastname" ng-model="lastname" />  
      15.     </div>  
      16.     <div class="form-group">  
      17.         <label for="country">  
      18.         Country:</label>  
      19.         <select class="form-control" id="country" ng-model="country" ng-options="c.Value as c.Text for c in countries" ng-change="getStates()">  
      20.             <option value="">-- Select Country --</option>  
      21.         </select>  
      22.     </div>  
      23.     <div class="form-group">  
      24.         <label for="state">  
      25.         State:</label>  
      26.         <select class="form-control" id="state" ng-model="state" ng-disabled="!states"ng-options="s.Value as s.Text for s in states">  
      27.             <option value="">-- Select State --</option>  
      28.         </select>  
      29.     </div>  
      30.     <div class="form-group">  
      31.         <label for="salary">  
      32.         Current Salary:</label>  
      33.         <input type="text" class="form-control" id="salary" ng-model="salary" />  
      34.     </div>  
      35.     <div class="form-group">  
      36.         <label for="dob">  
      37.         Date of Birth:</label>  
      38.         <input type="date" class="form-control" id="dob" ng-model="dob" />  
      39.     </div>  
      40.     <div class="form-group">  
      41.         <label for="description">  
      42.         Description:</label>  
      43.         <textarea rows="5" cols="10" class="form-control" id="description" ng-model="description"></textarea>  
      44.     </div>  
      45.     <div class="form-group checkbox">  
      46.         <label>  
      47.             <input type="checkbox" ng-model="active" />Active  
      48.         </label>  
      49.     </div>  
      50.     <a href="#/list" class="btn btn-info">Back to List</a>  
      51.     <button type="submit" class="btn btn-default" ng-click="save()">  
      52.         Submit  
      53.     </button>  
      54. </form>  
    3. Delete.html
      1. <h3>  
      2. Are you want to sure to delete this record?</h3>  
      3. <hr />  
      4. <form class="form-horizontal" style="max-width: 500px;">  
      5.     <div class="form-group">  
      6.         <label class="control-label col-xs-3">  
      7.         First Name :</label>  
      8.     <div class="col-xs-9">  
      9.         <p class="form-control-static">  
      10.         {{ firstname }}</p>  
      11.     </div>  
      12.     </div>  
      13.     <div class="form-group">  
      14.         <label class="control-label col-xs-3">  
      15.         Last Name :</label>  
      16.         <div class="col-xs-9">  
      17.             <p class="form-control-static">  
      18.             {{ lastname }}</p>  
      19.         </div>  
      20.     </div>  
      21.     <div class="form-group">  
      22.         <label class="control-label col-xs-3">  
      23.         Country :</label>  
      24.     <div class="col-xs-9">  
      25.         <p class="form-control-static">  
      26.         {{ country }}</p>  
      27.     </div>  
      28.     </div>  
      29.     <div class="form-group">  
      30.         <label class="control-label col-xs-3">  
      31.         State :</label>  
      32.     <div class="col-xs-9">  
      33.         <p class="form-control-static">  
      34.         {{ state }}</p>  
      35.     </div>  
      36.     </div>  
      37.     <div class="form-group">  
      38.         <label class="control-label col-xs-3">  
      39.         Salary :</label>  
      40.     <div class="col-xs-9">  
      41.         <p class="form-control-static">  
      42.         {{ salary }}</p>  
      43.         </div>  
      44.     </div>  
      45.     <div class="form-group">  
      46.         <label class="control-label col-xs-3">  
      47.         Date of Birth :</label>  
      48.         <div class="col-xs-9">  
      49.             <p class="form-control-static">  
      50.             {{ dob | date }}</p>  
      51.         </div>  
      52.     </div>  
      53.     <div class="form-group">  
      54.         <label class="control-label col-xs-3">  
      55.         Description :</label>  
      56.         <div class="col-xs-9">  
      57.             <p class="form-control-static">  
      58.             {{ description }}</p>  
      59.         </div>  
      60.     </div>  
      61.     <div class="form-group">  
      62.         <div class="col-xs-offset-3 col-xs-9">  
      63.             <span class="label" ng-class="{true:'label-success', false:'label-danger', '':'hidden'}[active]">  
      64.             {{ active ? 'Active' : 'In Active' }}</span>  
      65.         </div>  
      66.     </div>  
      67.     <div class="form-group">  
      68.         <div class="col-xs-offset-3 col-xs-9 text-center">  
      69.             <a href="#/list" class="btn btn-info">Back to List</a>  
      70.             <button type="submit" class="btn btn-primary" ng-click="delete()">  
      71.             Delete</button>  
      72.         </div>  
      73.     </div>  
      74. </form>  

    We had setup three views for list, create, edit and delete. Now we will implement the functionalities for these three views.

  11. Create a controller.js file and add the following code given below:
    1. var EmpControllers = angular.module("EmpControllers", []);  
    2. // this controller call the api method and display the list of employees  
    3. // in list.html  
    4. EmpControllers.controller("ListController", ['$scope''$http',  
    5.     function($scope, $http)  
    6.     {  
    7.         $http.get('/api/employee').success(function(data)  
    8.         {  
    9.             $scope.employees = data;  
    10.         });  
    11.     }  
    12. ]);  
    13. // this controller call the api method and display the record of selected employee  
    14. // in delete.html and provide an option for delete  
    15. EmpControllers.controller("DeleteController", ['$scope''$http''$routeParams''$location',  
    16.     function($scope, $http, $routeParams, $location)  
    17.     {  
    18.         $scope.id = $routeParams.id;  
    19.         $http.get('/api/employee/' + $routeParams.id).success(function(data)  
    20.         {  
    21.             $scope.firstname = data.FirstName;  
    22.             $scope.lastname = data.LastName;  
    23.             $scope.country = data.Country;  
    24.             $scope.state = data.State;  
    25.             $scope.salary = data.Salary;  
    26.             $scope.active = data.IsActive;  
    27.             $scope.dob = data.DateofBirth;  
    28.             $scope.description = data.Description;  
    29.         });  
    30.         $scope.delete = function()  
    31.         {  
    32.             $http.delete('/api/Employee/' + $scope.id).success(function(data)  
    33.             {  
    34.                 $location.path('/list');  
    35.             }).error(function(data)  
    36.             {  
    37.                 $scope.error = "An error has occured while deleting employee! " + data;  
    38.             });  
    39.         };  
    40.     }  
    41. ]);  
    42. // this controller call the api method and display the record of selected employee  
    43. // in edit.html and provide an option for create and modify the employee and save the employee record  
    44. EmpControllers.controller("EditController", ['$scope''$filter''$http''$routeParams''$location',  
    45.     function($scope, $filter, $http, $routeParams, $location)  
    46.     {  
    47.         $http.get('/api/country').success(function(data)  
    48.         {  
    49.             $scope.countries = data;  
    50.         });  
    51.         $scope.id = 0;  
    52.         $scope.getStates = function()  
    53.         {  
    54.             var country = $scope.country;  
    55.             if (country)  
    56.             {  
    57.                 $http.get('/api/country/' + country).success(function(data)  
    58.                 {  
    59.                     $scope.states = data;  
    60.                 });  
    61.             }  
    62.             else  
    63.             {  
    64.                 $scope.states = null;  
    65.             }  
    66.         }  
    67.         $scope.save = function()  
    68.         {  
    69.             var obj = {  
    70.                 EmployeeId: $scope.id,  
    71.                 FirstName: $scope.firstname,  
    72.                 LastName: $scope.lastname,  
    73.                 Country: $scope.country,  
    74.                 State: $scope.state,  
    75.                 Salary: $scope.salary,  
    76.                 IsActive: $scope.active,  
    77.                 Description: $scope.description,  
    78.                 DateofBirth: $scope.dob  
    79.             };  
    80.             if ($scope.id == 0)  
    81.             {  
    82.                 $http.post('/api/Employee/', obj).success(function(data)  
    83.                 {  
    84.                     $location.path('/list');  
    85.                 }).error(function(data)  
    86.                 {  
    87.                     $scope.error = "An error has occured while adding employee! " + data.ExceptionMessage;  
    88.                 });  
    89.             }  
    90.             else  
    91.             {  
    92.                 $http.put('/api/Employee/', obj).success(function(data)  
    93.                 {  
    94.                     $location.path('/list');  
    95.                 }).error(function(data)  
    96.                 {  
    97.                     console.log(data);  
    98.                     $scope.error = "An Error has occured while Saving customer! " + data.ExceptionMessage;  
    99.                 });  
    100.             }  
    101.         }  
    102.         if ($routeParams.id)  
    103.         {  
    104.             $scope.id = $routeParams.id;  
    105.             $scope.title = "Edit Employee";  
    106.             $http.get('/api/employee/' + $routeParams.id).success(function(data)  
    107.             {  
    108.                 $scope.firstname = data.FirstName;  
    109.                 $scope.lastname = data.LastName;  
    110.                 $scope.country = data.Country;  
    111.                 $scope.state = data.State;  
    112.                 $scope.salary = data.Salary;  
    113.                 $scope.active = data.IsActive;  
    114.                 $scope.description = data.Description;  
    115.                 $scope.dob = new Date(data.DateofBirth);  
    116.                 $scope.getStates();  
    117.             });  
    118.         }  
    119.         else  
    120.         {  
    121.             $scope.title = "Create New Employee";  
    122.         }  
    123.     }  
    124. ]);  
    In this controller.js we have multiple controllers for different views. Like ListController for list view (display the list of employees), Edit controller for edit view (create and modify the record), DeleteController for delete view (delete confirmation and delete the record).

Now we have implement ed and successfully completed all the steps.

To test the process you can build and run an application. I hope it works fine.

Thanks for reading this article. If you have any queries and suggestion please feel free to ask me and also your valuable comments are important for me and motivates me to write articles.

Read more articles on AngularJS,