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,
- Download the framework from the bellow link.
- In Visual Studio create a new project selecting “Web API”.
- Right click on the newly created solution and add a folder named as Framework (or whatever).
- 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.
- Right click on the solution > Add > New Project > Class Library(Package)
- Add three class library project following step 5. In this case I named those as Data, Repository and Service.
- 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.
Dependencies Installation
The demo project requires to install following dependencies (Nuget commands are included)-
- Angular JS (Install-Package angularjs)- In “WebApplication” grid project.
- Unity (Install-Package Unity)- In “ServiceApi” API project.
- Unity.MVC (Install-Package Unity.Mvc5)- In “ServiceApi” API project.
- 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.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Repository.Pattern.EF6;
-
- namespace Data.Models
- {
- public class Student: Entity
- {
- public int StudentID
- {
- get;
- set;
- }
- public string Name
- {
- get;
- set;
- }
- public string Email
- {
- get;
- set;
- }
- public string University
- {
- get;
- set;
- }
- }
- }
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
- using System.Data.Entity;
- using System.Data.Entity.Infrastructure;
- using Data.Models;
- using Repository.Pattern.Ef6;
-
- namespace Data
- {
- public partial class ApplicationContext: DataContext
- {
- static ApplicationContext()
- {
- Database.SetInitializer < ApplicationContext > (null);
- }
-
- public ApplicationContext(): base("Name=DefaultConnection") {}
-
- public DbSet < Student > Teams
- {
- get;
- set;
- }
-
- protected override void OnModelCreating(DbModelBuildermodelBuilder) {
-
-
- }
- }
- }
StudentRepository.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- using Data.Models;
- using Repository.Pattern.Repositories;
-
- namespace Repository
- {
- public static class StudentRepository
- {
- public static List < Student > GetAllStudent(this IRepositoryAsync < Student > repository)
- {
- var stds = repository.Queryable().ToList();
- return stds;
- }
- }
- }
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
- using Data.Models;
- using Service.Pattern;
- using System.Collections.Generic;
- using System.Linq;
- using Repository.Pattern.Repositories;
-
- namespace Service
- {
- public class StudentService: Service < Student > ,
- IStudentService
- {
- private readonly IRepositoryAsync < Student > _repository;
- public StudentService(IRepositoryAsync < Student > repository): base(repository) {
- _repository = repository;
- }
-
- public IEnumerable < Student > GetAll()
- {
- return _repository.Queryable().ToList();
- }
-
- public Student GetByStudentId(int studentId)
- {
- return _repository.Find(studentId);
- }
-
- public void InsertOrUpdate(Student student) {
- _repository.InsertOrUpdateGraph(student);
- }
- }
- }
IStudentService.cs
- using Data.Models;
- using Service.Pattern;
- using System.Collections.Generic;
-
- namespace Service
- {
- public interface IStudentService: IService < Student >
- {
- IEnumerable < Student > GetAll();
- StudentGetByStudentId(intstudentId);
- voidInsertOrUpdate(Student student);
- }
- }
Service section requires Repository.Rattern, Repository.Pattern.EF6, Service.Pattern, Repository and Data as reference.
Prepare ServiceApi Project: - Replace the UnityConfig.cs file in App_Start folder with the following code,
- using Microsoft.Practices.Unity;
- using System.Web.Http;
- using Data;
- using Repository.Pattern.DataContext;
- using Repository.Pattern.Ef6;
- using Repository.Pattern.Repositories;
- using Repository.Pattern.UnitOfWork;
- using Service;
- using Unity.WebApi;
-
- namespace ServiceApi
- {
- public static class UnityConfig
- {
- public static void Register Components()
- {
- var container = new UnityContainer();
-
-
-
-
-
-
- container.RegisterType < IDataContextAsync, ApplicationContext > (newHierarchicalLifetimeManager());
- container.RegisterType < IUnitOfWorkAsync, UnitOfWork > (newHierarchicalLifetimeManager());
- container.RegisterType(typeof(IRepositoryAsync < > ), typeof(Repository < > ));
- container.RegisterType < IStudentService, StudentService > ();
-
- GlobalConfiguration.Configuration.DependencyResolver = newUnityDependencyResolver(container);
- }
- }
- }
- Add a controller named StudentController.cs file with the following code,
- using System.Collections.Generic;
- using System.Threading.Tasks;
- using System.Web.Http;
- using System.Web.Http.Cors;
- using Data.Models;
- using Repository.Pattern.UnitOfWork;
- using Service;
-
- namespace ServiceApi.Controllers
- {
- [AllowAnonymous]
- [EnableCors(origins: "*", headers: "*", methods: "*")]
- public class StudentController: ApiController
- {
- private readonly IStudentService _studentService;
- private readonly IUnitOfWorkAsync _unitOfWorkAsync;
-
- public Student Controller(IStudentServicestudentService, IUnitOfWorkAsyncunitOfWorkAsync)
- {
- _studentService = studentService;
- _unitOfWorkAsync = unitOfWorkAsync;
- }
-
-
- public asyncTask < IHttpActionResult > Post(Student student)
- {
- _studentService.InsertOrUpdateGraph(student);
- await _unitOfWorkAsync.SaveChangesAsync();
- return Ok(student.StudentID);
- }
-
-
- public IEnumerable < Student > Get()
- {
- return _studentService.GetAll();
- }
-
-
- public IHttpActionResult Get(int id)
- {
- var student = _studentService.GetByStudentId(id);
- return Ok(student);
- }
-
-
- public IHttpActionResult Delete(int id)
- {
- var student = _studentService.GetByStudentId(id);
- _studentService.Delete(student);
- _unitOfWorkAsync.SaveChanges();
- return Ok(student.StudentID);
- }
- }
- }
ServiceApi section requires Repository.Rattern, Repository.Pattern.EF6, Service.Pattern, Repository, Service and Data as reference.
Prepare “WebApplicatio” Section:
- Under the project file add following views with code,
_Layout.cshtml
- <!DOCTYPEhtml>
-
- <html>
-
- <head>
- <metaname="viewport" content="width=device-width" />
- <title>Demo App</title>
-
- <linkhref="Content/Site.css" rel="stylesheet" type="text/css" />
- <linkhref="Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
- <scriptsrc="Scripts/modernizr-2.6.2.js">
- </script>
-
- </head>
-
- <body>
- <div>
- @RenderBody()
- </div>
- <scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js">
- </script>
-
- <scriptsrc="Scripts/jquery-2.2.0.min.js">
- </script>
- <scriptsrc="Scripts/angular.js">
- </script>
- @*
- <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.1.7/smart-table.js"></script>*@
- <scriptsrc="Scripts/angular-route.js">
- </script>
- <scriptsrc="Scripts/bootstrap.min.js">
- </script>
- <scriptsrc="app/StudentRoute.js">
- </script>
- <scriptsrc="Controllers/StudentController.js">
- </script>
- <scriptsrc="~/Service/StudentService.js">
- </script>
- </body>
-
- </html>
Index.cshtml
- <!DOCTYPEhtml>
- <html>
-
- <head>
- <metacharset="utf-8" />
- <metaname="viewport" content="width=device-width, initial-scale=1.0">
- <title>My ASP.NET Application</title>
- @{ Layout = "~/_Layout.cshtml"; }
- </head>
- <bodyng-app="StudentApp">
- <divclass="navbarnavbar-inverse navbar-fixed-top">
- <divclass="container">
- <divclass="navbar-header">
- <buttontype="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
- <spanclass="icon-bar">
- </span>
- <spanclass="icon-bar">
- </span>
- <spanclass="icon-bar">
- </span>
- </button>
- <span>Web Api2 with AngularJS Routing</span>
- </div>
- <divclass="navbar-collapse collapse">
- <ulclass="navnavbar-nav">
- </ul>
- </div>
- </div>
- </div>
-
- <divclass="container body-content">
- <divclass="row">
- <divclass="col-md-12">
- <divclass="page-header">
- <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>
- </div>
- </div>
-
- <divclass="col-md-12" ng-view>
- </div>
- </div>
-
- <hr/>
- <footer>
- <p>© My ASP.NET Application</p>
- </footer>
- </div>
- </body>
-
- </html>
- Create a folder Views and add following cshtml files with code,
Create.cshtml
- @{
- Layout = "~/_Layout.cshtml";
- }
-
- <div class="panel panel-default">
- <div class="panel-heading">Add New Student</div>
- <div class="panel-body">
-
- <form>
-
- <input type="hidden"ng-model="ID"value="{{student.StudentID}}">
- <div class="row">
- <div class="col-md-12">
- <div class="form-group">
- <input type="text"class="form-control"ng-model="Name"placeholder="Name"value="{{student.Name}}">
- </div>
- </div>
- </div>
-
- <div class="row">
- <div class="col-md-12">
- <div class="form-group">
- <input type="text"class="form-control"ng-model="Email"placeholder="Email"value="{{student.Email}}">
- </div>
- </div>
- </div>
-
- <div class="row">
- <div class="col-md-12">
- <div class="form-group">
- <input type="text"class="form-control"ng-model="University"placeholder="University"value="{{student.University}}">
- </div>
- </div>
- </div>
-
- <button type="button"class="btnbtn-default"ng-click="Save()">Save</button>
-
- </form>
-
- </div>
- </div>
List.cshtml
- @{
- Layout = "~/_Layout.cshtml";
- }
- <div>
- <a href="#/create"class="btnbtn-default">Create</a>
- </div>
- <br/>
-
- <div class="panel panel-default">
- <div class="panel-heading">Student List</div>
- <div class="panel-body">
-
- <div class="table-responsive">
- <table class="table table-striped table-bordered"st-safe-src="rowCollection"st-table="displayCollection"st-set-filter="myStrictFilter">
- <tr>
- <th st-sort="StudentID">Student ID</th>
- <th st-sort="Name">Name</th>
- <th st-sort="Email">Email</th>
- <th st-sort="University">University</th>
- <th></th>
- <th></th>
- </tr>
- <tr ng-repeat="iteminstudents">
- <td>{{item.StudentID}}</td>
- <td>{{item.Name}}</td>
- <td>{{item.Email}}</td>
- <td>{{item.University}}</td>
- <td>
- <a href="#/edit/{{item.StudentID}}"ng-click="GetStudent()"class="glyphiconglyphicon-edit"></a>
- </td>
- <td>
- <a href="javascript:void(0)"data-id="{{item.StudentID}}"class="glyphiconglyphicon-trash"ng-click="deleteStudent(this)"></a>
- </td>
- </tr>
- </table>
- </div>
-
- </div>
- </div>
- Create a folder app and add a js file named as StudentRoute.js with the following code,
- (function()
- {
- var app = angular.module('StudentApp', ['ngRoute']);
-
- app.config(function($routeProvider)
- {
- $routeProvider
-
- .when('/list',
- {
- templateUrl: 'Views/List.cshtml',
- controller: 'studentController'
- })
- .when('/create', {
- templateUrl: 'Views/Create.cshtml',
- controller: 'studentController'
- })
- .when('/edit/:id', {
- templateUrl: 'Views/Create.cshtml',
- controller: 'studentGetController'
- })
- .otherwise({
- redirectTo: '/list'
- });
- });
- }())
- Create a folder Service and add a StudentService.js file with following code,
- angular.module('StudentApp').factory('StudentService', ['$q', '$http', function($q, $http) {
-
- var baseUrl = 'http://localhost:57814/api/Student/';
-
- var studentService = {};
-
- studentService.Save = function(student)
- {
- var deferred = $q.defer();
- $http.post(baseUrl, student)
- .success(function(data)
- {
- deferred.resolve(data);
- }).error(function(error)
- {
- deferred.reject(error);
- });
- return deferred.promise;
- }
-
- studentService.Get = function(id)
- {
- var deferred = $q.defer();
- $http.get(baseUrl + id)
- .success(function(data) {
-
- deferred.resolve(data);
- }).error(function(error) {
- deferred.reject(error);
- });
- return deferred.promise;
- }
-
- studentService.GetAll = function()
- {
- var deferred = $q.defer();
- $http.get(baseUrl)
- .success(function(data) {
-
- deferred.resolve(data);
- }).error(function(error) {
- deferred.reject(error);
- });
- return deferred.promise;
- }
-
- studentService.Delete = function(id)
- {
- bootbox.confirm('Are you sure?', function(result)
- {
- if (result) {
- $http.delete(baseUrl + id).success(function(data)
- {
-
- }).error(function(data) {
- $scope.error = 'An error has occured while deleting employee! ' + data.ExceptionMessage;
- });
- }
- });
-
- return deferred.promise;
- }
-
- return studentService;
-
- }]);
- Create a folder Controllers and add a file StudentController.js with the following code,
- (function()
- {
- angular.module('StudentApp').controller('studentController', ['$scope', 'StudentService', '$location', function($scope, studentService, $location) {
-
- $scope.students = [];
-
- $scope.getAllStudents = function()
- {
- debugger
- studentService.GetAll().then(function(data)
- {
- if (data) {
- $scope.students = data;
- }
- });
- }
-
- $scope.deleteStudent = function(self)
- {
- studentService.Delete(self.$id).then(function(data)
- {
-
- $location.path('/list');
- });
- }
-
- $scope.saveStudent = function()
-
- {
- $scope.Save = function()
- {
-
- varobj =
- {
- StudentID: $scope.StudentID,
- Name: $scope.Name,
- Email: $scope.Email,
- University: $scope.University
- };
-
- studentService.Save(obj).then(function(data)
- {
- $location.path('/list');
- });
- }
- }
-
- $scope.getAllStudents();
-
- $scope.saveStudent();
-
- }]);
-
- angular.module('StudentApp').controller('studentGetController', ['$scope', 'StudentService', '$location', '$routeParams', function($scope, studentService, $location, $routeParams) {
-
- $scope.students = [];
-
- $scope.GetStudent = function()
- {
- studentService.Get($routeParams.id).then(function(data)
- {
- $scope.StudentID = data.StudentID;
- $scope.Name = data.Name;
- $scope.Email = data.Email;
- $scope.University = data.University;
- });
- }
-
- $scope.GetStudent();
-
- }]);
-
- }());
Finally the project is ready to run.
Download
Read more articles on AngularJS: