Complete Application Flow With Web API 2.0, CORS, Unit Of Work Repository Pattern, Unity And Angular JS Routing

The article will cover all the essential requirements to develop a CRUD application using Web API 2.0, CORS, Unit of Work Repository Pattern, Unity and AngularJS Routing.

Configure the Application

In this section, I’ll design the project structure using unit of work repository pattern,

  1. Download the framework from the bellow link.

  2. In Visual Studio create a new project selecting “Web API”.

    Web API

  3. Right click on the newly created solution and add a folder named as Framework (or whatever).

  4. Under the “Framework” folder add these three reference of solution file as existence item- Repository.Pattern, Repository.Pattern.EF6, Service.Pattern.

    Now it’s time to design the project structure. I’ll create grid solution under the solution. It consists of three class libraries as individual grids, one web api project which one I have already created and one empty project.

  5. Right click on the solution > Add > New Project > Class Library(Package)

  6. Add three class library project following step 5. In this case I named those as Data, Repository and Service.

  7. Add another empty project which will contain all the views and script.

So finally the project structure is ready and the solution will look like the below image.

solution

Dependencies Installation

The demo project requires to install following dependencies (Nuget commands are included)-

  1. Angular JS (Install-Package angularjs)- In “WebApplication” grid project.
  2. Unity (Install-Package Unity)- In “ServiceApi” API project.
  3. Unity.MVC (Install-Package Unity.Mvc5)- In “ServiceApi” API project.
  4. CORS (Install-PackageMicrosoft.Asp.Net.WebApi.Cors)- In “ServiceApi” API project.

To learn Cross Origin Resource Sharing (CORS) read my article,

Prepare “Data” Section:

Create a folder “Models” under “Data” grid project and add a class Student.cs with the following code snippet.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using Repository.Pattern.EF6;  
  7.   
  8. namespace Data.Models  
  9. {  
  10.     public class Student: Entity  
  11.     {  
  12.         public int StudentID  
  13.         {  
  14.             get;  
  15.             set;  
  16.         }  
  17.         public string Name   
  18.         {  
  19.             get;  
  20.             set;  
  21.         }  
  22.         public string Email  
  23.         {  
  24.             get;  
  25.             set;  
  26.         }  
  27.         public string University   
  28.         {  
  29.             get;  
  30.             set;  
  31.         }  
  32.     }  
  33. }  
Data section requires Repository.Rattern, Repository.Pattern.EF6, Service.Pattern as reference.

Prepare “Repository” Section:

Under Repository grid project add two cs file name as ApplicationContext.cs and StudentRepository.cs with the following code snippet.

ApplicationContext.cs
  1. using System.Data.Entity;  
  2. using System.Data.Entity.Infrastructure;  
  3. using Data.Models;  
  4. using Repository.Pattern.Ef6;  
  5.   
  6. namespace Data  
  7. {  
  8.     public partial class ApplicationContext: DataContext   
  9.     {  
  10.         static ApplicationContext()  
  11.         {  
  12.             Database.SetInitializer < ApplicationContext > (null);  
  13.         }  
  14.   
  15.         public ApplicationContext(): base("Name=DefaultConnection") {}  
  16.   
  17.         public DbSet < Student > Teams  
  18.         {  
  19.             get;  
  20.             set;  
  21.         }  
  22.   
  23.         protected override void OnModelCreating(DbModelBuildermodelBuilder) {  
  24.             //modelBuilder.Configurations.Add(new StudentMap());  
  25.   
  26.         }  
  27.     }  
  28. }  
StudentRepository.cs
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Text.RegularExpressions;  
  6. using System.Threading.Tasks;  
  7. using Data.Models;  
  8. using Repository.Pattern.Repositories;  
  9.   
  10. namespace Repository  
  11. {  
  12.     public static class StudentRepository   
  13.     {  
  14.         public static List < Student > GetAllStudent(this IRepositoryAsync < Student > repository)  
  15.         {  
  16.             var stds = repository.Queryable().ToList();  
  17.             return stds;  
  18.         }  
  19.     }  
  20. }  
Repository section requires Repository.Rattern, Repository.Pattern.EF6, Service.Pattern and Data as reference.

Prepare “Service” Section:

Under Service grid project add two cs file named as StudentService.cs and IStudentService.cs with following code snippets,

StudentService.cs
  1. using Data.Models;  
  2. using Service.Pattern;  
  3. using System.Collections.Generic;  
  4. using System.Linq;  
  5. using Repository.Pattern.Repositories;  
  6.   
  7. namespace Service  
  8. {  
  9.     public class StudentService: Service < Student > ,  
  10.     IStudentService  
  11.     {  
  12.         private readonly IRepositoryAsync < Student > _repository;  
  13.         public StudentService(IRepositoryAsync < Student > repository): base(repository) {  
  14.             _repository = repository;  
  15.         }  
  16.   
  17.         public IEnumerable < Student > GetAll()  
  18.         {  
  19.             return _repository.Queryable().ToList();  
  20.         }  
  21.   
  22.         public Student GetByStudentId(int studentId)  
  23.         {  
  24.             return _repository.Find(studentId);  
  25.         }  
  26.   
  27.         public void InsertOrUpdate(Student student) {  
  28.             _repository.InsertOrUpdateGraph(student);  
  29.         }  
  30.     }  
  31. }  
IStudentService.cs
  1. using Data.Models;  
  2. using Service.Pattern;  
  3. using System.Collections.Generic;  
  4.   
  5. namespace Service  
  6. {  
  7.     public interface IStudentService: IService < Student >  
  8.       {  
  9.         IEnumerable < Student > GetAll();  
  10.         StudentGetByStudentId(intstudentId);  
  11.         voidInsertOrUpdate(Student student);  
  12.     }  
  13. }  
Service section requires Repository.Rattern, Repository.Pattern.EF6, Service.Pattern, Repository and Data as reference.

Prepare ServiceApi Project: 
  1. Replace the UnityConfig.cs file in App_Start folder with the following code,
    1. using Microsoft.Practices.Unity;  
    2. using System.Web.Http;  
    3. using Data;  
    4. using Repository.Pattern.DataContext;  
    5. using Repository.Pattern.Ef6;  
    6. using Repository.Pattern.Repositories;  
    7. using Repository.Pattern.UnitOfWork;  
    8. using Service;  
    9. using Unity.WebApi;  
    10.   
    11. namespace ServiceApi   
    12. {  
    13.     public static class UnityConfig  
    14.     {  
    15.         public static void Register Components()  
    16.         {  
    17.             var container = new UnityContainer();  
    18.   
    19.             // register all your components with the container here  
    20.             // it is NOT necessary to register your controllers  
    21.   
    22.             // e.g. container.RegisterType<ITestService, TestService>();  
    23.   
    24.             container.RegisterType < IDataContextAsync, ApplicationContext > (newHierarchicalLifetimeManager());  
    25.             container.RegisterType < IUnitOfWorkAsync, UnitOfWork > (newHierarchicalLifetimeManager());  
    26.             container.RegisterType(typeof(IRepositoryAsync < > ), typeof(Repository < > ));  
    27.             container.RegisterType < IStudentService, StudentService > ();  
    28.   
    29.             GlobalConfiguration.Configuration.DependencyResolver = newUnityDependencyResolver(container);  
    30.         }  
    31.     }  
    32. }  
  2. Add a controller named StudentController.cs file with the following code,
    1. using System.Collections.Generic;  
    2. using System.Threading.Tasks;  
    3. using System.Web.Http;  
    4. using System.Web.Http.Cors;  
    5. using Data.Models;  
    6. using Repository.Pattern.UnitOfWork;  
    7. using Service;  
    8.   
    9. namespace ServiceApi.Controllers  
    10. {  
    11.     [AllowAnonymous]  
    12.     [EnableCors(origins: "*", headers: "*", methods: "*")]  
    13.     public class StudentController: ApiController   
    14.     {  
    15.         private readonly IStudentService _studentService;  
    16.         private readonly IUnitOfWorkAsync _unitOfWorkAsync;  
    17.   
    18.         public Student Controller(IStudentServicestudentService, IUnitOfWorkAsyncunitOfWorkAsync)  
    19.         {  
    20.             _studentService = studentService;  
    21.             _unitOfWorkAsync = unitOfWorkAsync;  
    22.         }  
    23.   
    24.         // POST api/<controller>  
    25.         public asyncTask < IHttpActionResult > Post(Student student)  
    26.         {  
    27.             _studentService.InsertOrUpdateGraph(student);  
    28.             await _unitOfWorkAsync.SaveChangesAsync();  
    29.             return Ok(student.StudentID);  
    30.         }  
    31.   
    32.         // GET api/<controller>  
    33.         public IEnumerable < Student > Get()  
    34.         {  
    35.             return _studentService.GetAll();  
    36.         }  
    37.   
    38.         // GET api/<controller>/5  
    39.         public IHttpActionResult Get(int id)  
    40.         {  
    41.             var student = _studentService.GetByStudentId(id);  
    42.             return Ok(student);  
    43.         }  
    44.   
    45.         // DELETE api/values/5  
    46.         public IHttpActionResult Delete(int id)  
    47.         {  
    48.             var student = _studentService.GetByStudentId(id);  
    49.             _studentService.Delete(student);  
    50.             _unitOfWorkAsync.SaveChanges();  
    51.             return Ok(student.StudentID);  
    52.         }  
    53.     }  
    54. }  

ServiceApi section requires Repository.Rattern, Repository.Pattern.EF6, Service.Pattern, Repository, Service and Data as reference.

Prepare “WebApplicatio” Section:

  1. Under the project file add following views with code,

    _Layout.cshtml
    1. <!DOCTYPEhtml>  
    2.   
    3. <html>  
    4.   
    5. <head>  
    6.     <metaname="viewport" content="width=device-width" />  
    7.     <title>Demo App</title>  
    8.   
    9.     <linkhref="Content/Site.css" rel="stylesheet" type="text/css" />  
    10.     <linkhref="Content/bootstrap.min.css" rel="stylesheet" type="text/css" />  
    11.     <scriptsrc="Scripts/modernizr-2.6.2.js">  
    12.         </script>  
    13.   
    14. </head>  
    15.   
    16. <body>  
    17.     <div>  
    18.         @RenderBody()  
    19.     </div>  
    20.     <scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js">  
    21.         </script>  
    22.   
    23.         <scriptsrc="Scripts/jquery-2.2.0.min.js">  
    24.             </script>  
    25.             <scriptsrc="Scripts/angular.js">  
    26.                 </script>  
    27.                 @*  
    28.                 <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.1.7/smart-table.js"></script>*@  
    29.                 <scriptsrc="Scripts/angular-route.js">  
    30.                     </script>  
    31.                     <scriptsrc="Scripts/bootstrap.min.js">  
    32.                         </script>  
    33.                         <scriptsrc="app/StudentRoute.js">  
    34.                             </script>  
    35.                             <scriptsrc="Controllers/StudentController.js">  
    36.                                 </script>  
    37.                                 <scriptsrc="~/Service/StudentService.js">  
    38.                                     </script>  
    39. </body>  
    40.   
    41. </html>  
    Index.cshtml
    1. <!DOCTYPEhtml>  
    2. <html>  
    3.   
    4. <head>  
    5.     <metacharset="utf-8" />  
    6.     <metaname="viewport" content="width=device-width, initial-scale=1.0">  
    7.         <title>My ASP.NET Application</title>  
    8.         @{ Layout = "~/_Layout.cshtml"; }  
    9. </head>  
    10. <bodyng-app="StudentApp">  
    11.     <divclass="navbarnavbar-inverse navbar-fixed-top">  
    12.         <divclass="container">  
    13.             <divclass="navbar-header">  
    14.                 <buttontype="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">  
    15.                     <spanclass="icon-bar">  
    16.                         </span>  
    17.                         <spanclass="icon-bar">  
    18.                             </span>  
    19.                             <spanclass="icon-bar">  
    20.                                 </span>  
    21.                                 </button>  
    22.                                 <span>Web Api2 with AngularJS Routing</span>  
    23.                                 </div>  
    24.                                 <divclass="navbar-collapse collapse">  
    25.                                     <ulclass="navnavbar-nav">  
    26.                                         </ul>  
    27.                                         </div>  
    28.                                         </div>  
    29.                                         </div>  
    30.   
    31.                                         <divclass="container body-content">  
    32.                                             <divclass="row">  
    33.                                                 <divclass="col-md-12">  
    34.                                                     <divclass="page-header">  
    35.                                                         <h1class="title-header">DEMO APP<small> Single Page with AngularJS Routing, Unit of Works- High level system architecture, Web API 2.0, Cross Origin Resource Sharing(CORS), Separation of Concern(SOC)</small></h1>  
    36.                                                             </div>  
    37.                                                             </div>  
    38.   
    39.                                                             <divclass="col-md-12" ng-view>  
    40.                                                                 </div>  
    41.                                                                 </div>  
    42.   
    43.                                                                 <hr/>  
    44.                                                                 <footer>  
    45.                                                                     <p>© My ASP.NET Application</p>  
    46.                                                                 </footer>  
    47.                                                                 </div>  
    48.                                                                 </body>  
    49.   
    50. </html>  

  2. Create a folder Views and add following cshtml files with code,

    Create.cshtml
    1. @{  
    2. Layout = "~/_Layout.cshtml";  
    3. }  
    4.   
    5. <div class="panel panel-default">  
    6. <div class="panel-heading">Add New Student</div>  
    7. <div class="panel-body">  
    8.   
    9. <form>  
    10.   
    11. <input type="hidden"ng-model="ID"value="{{student.StudentID}}">  
    12. <div class="row">  
    13. <div class="col-md-12">  
    14. <div class="form-group">  
    15. <input type="text"class="form-control"ng-model="Name"placeholder="Name"value="{{student.Name}}">  
    16. </div>  
    17. </div>  
    18. </div>  
    19.   
    20. <div class="row">  
    21. <div class="col-md-12">  
    22. <div class="form-group">  
    23. <input type="text"class="form-control"ng-model="Email"placeholder="Email"value="{{student.Email}}">  
    24. </div>  
    25. </div>  
    26. </div>  
    27.   
    28. <div class="row">  
    29. <div class="col-md-12">  
    30. <div class="form-group">  
    31. <input type="text"class="form-control"ng-model="University"placeholder="University"value="{{student.University}}">  
    32. </div>  
    33. </div>  
    34. </div>  
    35.   
    36. <button type="button"class="btnbtn-default"ng-click="Save()">Save</button>  
    37.   
    38. </form>  
    39.   
    40. </div>  
    41. </div>  
    List.cshtml
    1. @{  
    2. Layout = "~/_Layout.cshtml";  
    3. }  
    4. <div>  
    5. <a href="#/create"class="btnbtn-default">Create</a>  
    6. </div>  
    7. <br/>  
    8.   
    9. <div class="panel panel-default">  
    10. <div class="panel-heading">Student List</div>  
    11. <div class="panel-body">  
    12.   
    13. <div class="table-responsive">  
    14. <table class="table table-striped table-bordered"st-safe-src="rowCollection"st-table="displayCollection"st-set-filter="myStrictFilter">  
    15. <tr>  
    16. <th st-sort="StudentID">Student ID</th>  
    17. <th st-sort="Name">Name</th>  
    18. <th st-sort="Email">Email</th>  
    19. <th st-sort="University">University</th>  
    20. <th></th>  
    21. <th></th>  
    22. </tr>  
    23. <tr ng-repeat="iteminstudents">  
    24. <td>{{item.StudentID}}</td>  
    25. <td>{{item.Name}}</td>  
    26. <td>{{item.Email}}</td>  
    27. <td>{{item.University}}</td>  
    28. <td>  
    29. <a href="#/edit/{{item.StudentID}}"ng-click="GetStudent()"class="glyphiconglyphicon-edit"></a>  
    30. </td>  
    31. <td>  
    32. <a href="javascript:void(0)"data-id="{{item.StudentID}}"class="glyphiconglyphicon-trash"ng-click="deleteStudent(this)"></a>  
    33. </td>  
    34. </tr>  
    35. </table>  
    36. </div>  
    37.   
    38. </div>  
    39. </div>  

  3. Create a folder app and add a js file named as StudentRoute.js with the following code,
    1. (function()  
    2.  {  
    3.     var app = angular.module('StudentApp', ['ngRoute']);  
    4.   
    5.     app.config(function($routeProvider)  
    6.     {  
    7.         $routeProvider  
    8.   
    9.             .when('/list',  
    10.             {  
    11.                 templateUrl: 'Views/List.cshtml',  
    12.                 controller: 'studentController'  
    13.             })  
    14.             .when('/create', {  
    15.                 templateUrl: 'Views/Create.cshtml',  
    16.                 controller: 'studentController'  
    17.             })  
    18.             .when('/edit/:id', {  
    19.                 templateUrl: 'Views/Create.cshtml',  
    20.                 controller: 'studentGetController'  
    21.             })  
    22.             .otherwise({  
    23.                 redirectTo: '/list'  
    24.             });  
    25.     });  
    26. }())  
  4. Create a folder Service and add a StudentService.js file with following code,
    1. angular.module('StudentApp').factory('StudentService', ['$q''$http', function($q, $http) {  
    2.   
    3.     var baseUrl = 'http://localhost:57814/api/Student/';  
    4.   
    5.     var studentService = {};  
    6.   
    7.     studentService.Save = function(student)  
    8.     {  
    9.         var deferred = $q.defer();  
    10.         $http.post(baseUrl, student)  
    11.             .success(function(data)  
    12.             {  
    13.                 deferred.resolve(data);  
    14.             }).error(function(error)  
    15.             {  
    16.                 deferred.reject(error);  
    17.             });  
    18.         return deferred.promise;  
    19.     }  
    20.   
    21.     studentService.Get = function(id)  
    22.     {  
    23.         var deferred = $q.defer();  
    24.         $http.get(baseUrl + id)  
    25.             .success(function(data) {  
    26.   
    27.                 deferred.resolve(data);  
    28.             }).error(function(error) {  
    29.                 deferred.reject(error);  
    30.             });  
    31.         return deferred.promise;  
    32.     }  
    33.   
    34.     studentService.GetAll = function()   
    35.     {  
    36.         var deferred = $q.defer();  
    37.         $http.get(baseUrl)  
    38.             .success(function(data) {  
    39.   
    40.                 deferred.resolve(data);  
    41.             }).error(function(error) {  
    42.                 deferred.reject(error);  
    43.             });  
    44.         return deferred.promise;  
    45.     }  
    46.   
    47.     studentService.Delete = function(id)  
    48.     {  
    49.         bootbox.confirm('Are you sure?', function(result)   
    50.                         {  
    51.             if (result) {  
    52.                 $http.delete(baseUrl + id).success(function(data)   
    53.                                                    {  
    54.   
    55.                 }).error(function(data) {  
    56.                     $scope.error = 'An error has occured while deleting employee! ' + data.ExceptionMessage;  
    57.                 });  
    58.             }  
    59.         });  
    60.   
    61.         return deferred.promise;  
    62.     }  
    63.   
    64.     return studentService;  
    65.   
    66. }]);  
  5. Create a folder Controllers and add a file StudentController.js with the following code,
    1. (function()   
    2.  {  
    3.     angular.module('StudentApp').controller('studentController', ['$scope''StudentService''$location', function($scope, studentService, $location) {  
    4.   
    5.         $scope.students = [];  
    6.   
    7.         $scope.getAllStudents = function()  
    8.         {  
    9.             debugger  
    10.             studentService.GetAll().then(function(data)  
    11.                                          {  
    12.                 if (data) {  
    13.                     $scope.students = data;  
    14.                 }  
    15.             });  
    16.         }  
    17.   
    18.         $scope.deleteStudent = function(self)  
    19.         {  
    20.             studentService.Delete(self.$id).then(function(data)  
    21.             {  
    22.                 //$scope.getAllStudents();  
    23.                 $location.path('/list');  
    24.             });  
    25.         }  
    26.   
    27.         $scope.saveStudent = function()  
    28.           
    29.         {  
    30.             $scope.Save = function()  
    31.             {  
    32.   
    33.                 varobj =  
    34.                   {  
    35.                     StudentID: $scope.StudentID,  
    36.                     Name: $scope.Name,  
    37.                     Email: $scope.Email,  
    38.                     University: $scope.University  
    39.                 };  
    40.   
    41.                 studentService.Save(obj).then(function(data)  
    42.                  {  
    43.                     $location.path('/list');  
    44.                 });  
    45.             }  
    46.         }  
    47.   
    48.         $scope.getAllStudents();  
    49.   
    50.         $scope.saveStudent();  
    51.   
    52.     }]);  
    53.   
    54.     angular.module('StudentApp').controller('studentGetController', ['$scope''StudentService''$location''$routeParams', function($scope, studentService, $location, $routeParams) {  
    55.   
    56.         $scope.students = [];  
    57.   
    58.         $scope.GetStudent = function()  
    59.         {  
    60.             studentService.Get($routeParams.id).then(function(data)  
    61.              {  
    62.                 $scope.StudentID = data.StudentID;  
    63.                 $scope.Name = data.Name;  
    64.                 $scope.Email = data.Email;  
    65.                 $scope.University = data.University;  
    66.             });  
    67.         }  
    68.   
    69.         $scope.GetStudent();  
    70.   
    71.     }]);  
    72.   
    73. }());  

Finally the project is ready to run.

Download

Read more articles on AngularJS:


Similar Articles