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. namespace Data.Models
  8. {
  9. public class Student: Entity
  10. {
  11. public int StudentID
  12. {
  13. get;
  14. set;
  15. }
  16. public string Name
  17. {
  18. get;
  19. set;
  20. }
  21. public string Email
  22. {
  23. get;
  24. set;
  25. }
  26. public string University
  27. {
  28. get;
  29. set;
  30. }
  31. }
  32. }
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. namespace Data
  6. {
  7. public partial class ApplicationContext: DataContext
  8. {
  9. static ApplicationContext()
  10. {
  11. Database.SetInitializer < ApplicationContext > (null);
  12. }
  13. public ApplicationContext(): base("Name=DefaultConnection") {}
  14. public DbSet < Student > Teams
  15. {
  16. get;
  17. set;
  18. }
  19. protected override void OnModelCreating(DbModelBuildermodelBuilder) {
  20. //modelBuilder.Configurations.Add(new StudentMap());
  21. }
  22. }
  23. }
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. namespace Repository
  10. {
  11. public static class StudentRepository
  12. {
  13. public static List < Student > GetAllStudent(this IRepositoryAsync < Student > repository)
  14. {
  15. var stds = repository.Queryable().ToList();
  16. return stds;
  17. }
  18. }
  19. }
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. namespace Service
  7. {
  8. public class StudentService: Service < Student > ,
  9. IStudentService
  10. {
  11. private readonly IRepositoryAsync < Student > _repository;
  12. public StudentService(IRepositoryAsync < Student > repository): base(repository) {
  13. _repository = repository;
  14. }
  15. public IEnumerable < Student > GetAll()
  16. {
  17. return _repository.Queryable().ToList();
  18. }
  19. public Student GetByStudentId(int studentId)
  20. {
  21. return _repository.Find(studentId);
  22. }
  23. public void InsertOrUpdate(Student student) {
  24. _repository.InsertOrUpdateGraph(student);
  25. }
  26. }
  27. }
IStudentService.cs
  1. using Data.Models;
  2. using Service.Pattern;
  3. using System.Collections.Generic;
  4. namespace Service
  5. {
  6. public interface IStudentService: IService < Student >
  7. {
  8. IEnumerable < Student > GetAll();
  9. StudentGetByStudentId(intstudentId);
  10. voidInsertOrUpdate(Student student);
  11. }
  12. }
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. namespace ServiceApi
    11. {
    12. public static class UnityConfig
    13. {
    14. public static void Register Components()
    15. {
    16. var container = new UnityContainer();
    17. // register all your components with the container here
    18. // it is NOT necessary to register your controllers
    19. // e.g. container.RegisterType<ITestService, TestService>();
    20. container.RegisterType < IDataContextAsync, ApplicationContext > (newHierarchicalLifetimeManager());
    21. container.RegisterType < IUnitOfWorkAsync, UnitOfWork > (newHierarchicalLifetimeManager());
    22. container.RegisterType(typeof(IRepositoryAsync < > ), typeof(Repository < > ));
    23. container.RegisterType < IStudentService, StudentService > ();
    24. GlobalConfiguration.Configuration.DependencyResolver = newUnityDependencyResolver(container);
    25. }
    26. }
    27. }
  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. namespace ServiceApi.Controllers
    9. {
    10. [AllowAnonymous]
    11. [EnableCors(origins: "*", headers: "*", methods: "*")]
    12. public class StudentController: ApiController
    13. {
    14. private readonly IStudentService _studentService;
    15. private readonly IUnitOfWorkAsync _unitOfWorkAsync;
    16. public Student Controller(IStudentServicestudentService, IUnitOfWorkAsyncunitOfWorkAsync)
    17. {
    18. _studentService = studentService;
    19. _unitOfWorkAsync = unitOfWorkAsync;
    20. }
    21. // POST api/<controller>
    22. public asyncTask < IHttpActionResult > Post(Student student)
    23. {
    24. _studentService.InsertOrUpdateGraph(student);
    25. await _unitOfWorkAsync.SaveChangesAsync();
    26. return Ok(student.StudentID);
    27. }
    28. // GET api/<controller>
    29. public IEnumerable < Student > Get()
    30. {
    31. return _studentService.GetAll();
    32. }
    33. // GET api/<controller>/5
    34. public IHttpActionResult Get(int id)
    35. {
    36. var student = _studentService.GetByStudentId(id);
    37. return Ok(student);
    38. }
    39. // DELETE api/values/5
    40. public IHttpActionResult Delete(int id)
    41. {
    42. var student = _studentService.GetByStudentId(id);
    43. _studentService.Delete(student);
    44. _unitOfWorkAsync.SaveChanges();
    45. return Ok(student.StudentID);
    46. }
    47. }
    48. }

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

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

    Create.cshtml
    1. @{
    2. Layout = "~/_Layout.cshtml";
    3. }
    4. <div class="panel panel-default">
    5. <div class="panel-heading">Add New Student</div>
    6. <div class="panel-body">
    7. <form>
    8. <input type="hidden"ng-model="ID"value="{{student.StudentID}}">
    9. <div class="row">
    10. <div class="col-md-12">
    11. <div class="form-group">
    12. <input type="text"class="form-control"ng-model="Name"placeholder="Name"value="{{student.Name}}">
    13. </div>
    14. </div>
    15. </div>
    16. <div class="row">
    17. <div class="col-md-12">
    18. <div class="form-group">
    19. <input type="text"class="form-control"ng-model="Email"placeholder="Email"value="{{student.Email}}">
    20. </div>
    21. </div>
    22. </div>
    23. <div class="row">
    24. <div class="col-md-12">
    25. <div class="form-group">
    26. <input type="text"class="form-control"ng-model="University"placeholder="University"value="{{student.University}}">
    27. </div>
    28. </div>
    29. </div>
    30. <button type="button"class="btnbtn-default"ng-click="Save()">Save</button>
    31. </form>
    32. </div>
    33. </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. <div class="panel panel-default">
    9. <div class="panel-heading">Student List</div>
    10. <div class="panel-body">
    11. <div class="table-responsive">
    12. <table class="table table-striped table-bordered"st-safe-src="rowCollection"st-table="displayCollection"st-set-filter="myStrictFilter">
    13. <tr>
    14. <th st-sort="StudentID">Student ID</th>
    15. <th st-sort="Name">Name</th>
    16. <th st-sort="Email">Email</th>
    17. <th st-sort="University">University</th>
    18. <th></th>
    19. <th></th>
    20. </tr>
    21. <tr ng-repeat="iteminstudents">
    22. <td>{{item.StudentID}}</td>
    23. <td>{{item.Name}}</td>
    24. <td>{{item.Email}}</td>
    25. <td>{{item.University}}</td>
    26. <td>
    27. <a href="#/edit/{{item.StudentID}}"ng-click="GetStudent()"class="glyphiconglyphicon-edit"></a>
    28. </td>
    29. <td>
    30. <a href="javascript:void(0)"data-id="{{item.StudentID}}"class="glyphiconglyphicon-trash"ng-click="deleteStudent(this)"></a>
    31. </td>
    32. </tr>
    33. </table>
    34. </div>
    35. </div>
    36. </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. app.config(function($routeProvider)
    5. {
    6. $routeProvider
    7. .when('/list',
    8. {
    9. templateUrl: 'Views/List.cshtml',
    10. controller: 'studentController'
    11. })
    12. .when('/create', {
    13. templateUrl: 'Views/Create.cshtml',
    14. controller: 'studentController'
    15. })
    16. .when('/edit/:id', {
    17. templateUrl: 'Views/Create.cshtml',
    18. controller: 'studentGetController'
    19. })
    20. .otherwise({
    21. redirectTo: '/list'
    22. });
    23. });
    24. }())
  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. var baseUrl = 'http://localhost:57814/api/Student/';
    3. var studentService = {};
    4. studentService.Save = function(student)
    5. {
    6. var deferred = $q.defer();
    7. $http.post(baseUrl, student)
    8. .success(function(data)
    9. {
    10. deferred.resolve(data);
    11. }).error(function(error)
    12. {
    13. deferred.reject(error);
    14. });
    15. return deferred.promise;
    16. }
    17. studentService.Get = function(id)
    18. {
    19. var deferred = $q.defer();
    20. $http.get(baseUrl + id)
    21. .success(function(data) {
    22. deferred.resolve(data);
    23. }).error(function(error) {
    24. deferred.reject(error);
    25. });
    26. return deferred.promise;
    27. }
    28. studentService.GetAll = function()
    29. {
    30. var deferred = $q.defer();
    31. $http.get(baseUrl)
    32. .success(function(data) {
    33. deferred.resolve(data);
    34. }).error(function(error) {
    35. deferred.reject(error);
    36. });
    37. return deferred.promise;
    38. }
    39. studentService.Delete = function(id)
    40. {
    41. bootbox.confirm('Are you sure?', function(result)
    42. {
    43. if (result) {
    44. $http.delete(baseUrl + id).success(function(data)
    45. {
    46. }).error(function(data) {
    47. $scope.error = 'An error has occured while deleting employee! ' + data.ExceptionMessage;
    48. });
    49. }
    50. });
    51. return deferred.promise;
    52. }
    53. return studentService;
    54. }]);
  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. $scope.students = [];
    5. $scope.getAllStudents = function()
    6. {
    7. debugger
    8. studentService.GetAll().then(function(data)
    9. {
    10. if (data) {
    11. $scope.students = data;
    12. }
    13. });
    14. }
    15. $scope.deleteStudent = function(self)
    16. {
    17. studentService.Delete(self.$id).then(function(data)
    18. {
    19. //$scope.getAllStudents();
    20. $location.path('/list');
    21. });
    22. }
    23. $scope.saveStudent = function()
    24. {
    25. $scope.Save = function()
    26. {
    27. varobj =
    28. {
    29. StudentID: $scope.StudentID,
    30. Name: $scope.Name,
    31. Email: $scope.Email,
    32. University: $scope.University
    33. };
    34. studentService.Save(obj).then(function(data)
    35. {
    36. $location.path('/list');
    37. });
    38. }
    39. }
    40. $scope.getAllStudents();
    41. $scope.saveStudent();
    42. }]);
    43. angular.module('StudentApp').controller('studentGetController', ['$scope', 'StudentService', '$location', '$routeParams', function($scope, studentService, $location, $routeParams) {
    44. $scope.students = [];
    45. $scope.GetStudent = function()
    46. {
    47. studentService.Get($routeParams.id).then(function(data)
    48. {
    49. $scope.StudentID = data.StudentID;
    50. $scope.Name = data.Name;
    51. $scope.Email = data.Email;
    52. $scope.University = data.University;
    53. });
    54. }
    55. $scope.GetStudent();
    56. }]);
    57. }());

Finally the project is ready to run.

Download

Read more articles on AngularJS: