In this article I am going to demonstrate about how can we create basic crud (create, read, update and delete) using MVC Web API, SQL Server and Angular JS.
In this demo application our main concern will be on Angular JS data-binding and routing. I also used a Entity Framework Code First approach for database operation.
Functionalities present in this application:
a) Data Binding using Angularjs
b) Client side routing using Angular Routing
c) Cascading Dropdown using AngularJS
d) Conditional formatting using Angularjs
e) 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:
2) Employee Page for Create and Edit a record.
3) Employee Delete Confirmation page with details:
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:
a) AngularJS.Core
b) AngularJS.Route
c) Bootstrap
d) EntityFramework
3) Create a Model named Employee in Models folder and replace the code with the following:
public class Employee
{
public int EmployeeId { get; set; }
[Required]
[StringLength(20)]
public string FirstName { get; set; }
[Required]
[StringLength(20)]
public string LastName { get; set; }
[Required]
[StringLength(100)]
public string Description { get; set; }
public float Salary { get; set; }
[Required]
[StringLength(50)]
public string Country { get; set; }
[Required]
[StringLength(50)]
public string State { get; set; }
public DateTime DateofBirth { get; set; }
public bool IsActive { get; set; }
}
public class EmployeeDbContext : DbContext
{
public EmployeeDbContext()
: base()
{
Database.SetInitializer<EmployeeDbContext>(new EmployeeDbContextInitializer());
}
public DbSet<Employee> Employees { get; set; }
}
public class EmployeeDbContextInitializer : DropCreateDatabaseIfModelChanges<EmployeeDbContext>
{
protected override void Seed(EmployeeDbContext context)
{
var list = new List<Employee>
{
new Employee { FirstName = "Rohit", LastName = "Kesharwani", Description = "Rohit Kesharwani", DateofBirth = DateTime.Now.AddYears(-23), Country = "IN", State="UP", Salary = 99999, IsActive = true },
new Employee { FirstName = "Rahul", LastName = "Singh", Description = "Rahul Singh", DateofBirth = DateTime.Now.AddYears(-25), Country = "IN", State="MP", Salary = 49999.28f, IsActive = true }
};
list.ForEach(m =>
{
context.Employees.Add(m);
});
context.SaveChanges();
base.Seed(context);
}
}
4) Add a connection string with same name of EmployeeDbContext in web.config:
<connectionStrings>
<add name="EmployeeDbContext" connectionString="Data Source=(local);Initial Catalog=EmpDb;Integrated Security=true;" providerName="System.Data.SqlClient"/>
</connectionStrings>
5) Now create a Employee API controller to perform crud in database:
public class EmployeeController : ApiController
{
EmployeeDbContext db = new EmployeeDbContext();
// GET api/employee
[ActionName("get"), HttpGet]
public IEnumerable<Employee> Emps()
{
return db.Employees.ToList();
}
// GET api/employee/5
public Employee Get(int id)
{
return db.Employees.Find(id);
}
// POST api/employee
public HttpResponseMessage Post(Employee model)
{
if (ModelState.IsValid)
{
db.Employees.Add(model);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, model);
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
// PUT api/employee/5
public HttpResponseMessage Put(Employee model)
{
if (ModelState.IsValid)
{
db.Entry(model).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, model);
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
// DELETE api/employee/5
public HttpResponseMessage Delete(int id)
{
Employee emp = db.Employees.Find(id);
if (emp == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
db.Employees.Remove(emp);
db.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK, emp);
}
6) Also create a Country controller to retrieve country and its states from server side in order to implement cascading dropdown list:
public class CountryController : ApiController
{
// GET api/country
public IEnumerable<System.Web.Mvc.SelectListItem> Get()
{
List<System.Web.Mvc.SelectListItem> countries = new List<System.Web.Mvc.SelectListItem>
{
new System.Web.Mvc.SelectListItem { Text = "India", Value="IN" },
new System.Web.Mvc.SelectListItem { Text = "United States", Value="US" },
new System.Web.Mvc.SelectListItem { Text = "United Kingdom", Value="UK" },
new System.Web.Mvc.SelectListItem { Text = "Australlia", Value="CA" }
};
return countries;
}
// GET api/country/5
public IEnumerable<System.Web.Mvc.SelectListItem> Get(string id)
{
List<System.Web.Mvc.SelectListItem> states = new List<System.Web.Mvc.SelectListItem>();
switch (id)
{
case "IN":
states.Add(new System.Web.Mvc.SelectListItem { Text = "Uttar Pradesh", Value = "UP" });
states.Add(new System.Web.Mvc.SelectListItem { Text = "Madhya Pradesh", Value = "MP" });
states.Add(new System.Web.Mvc.SelectListItem { Text = "Delhi", Value = "DL" });
states.Add(new System.Web.Mvc.SelectListItem { Text = "Kanpur", Value = "KN" });
break;
case "US":
states.Add(new System.Web.Mvc.SelectListItem { Text = "California", Value = "CA" });
states.Add(new System.Web.Mvc.SelectListItem { Text = "Newyork", Value = "NY" });
break;
case "UK":
states.Add(new System.Web.Mvc.SelectListItem { Text = "London", Value = "LN" });
states.Add(new System.Web.Mvc.SelectListItem { Text = "Paris", Value = "PR" });
break;
case "CA":
states.Add(new System.Web.Mvc.SelectListItem { Text = "Sydney", Value = "SD" });
states.Add(new System.Web.Mvc.SelectListItem { Text = "Melbourne", Value = "MB" });
break;
}
return states;
}
}
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:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
8) Index view with js and css references:
@{
Layout = null;
}
<!DOCTYPE html>
<html ng-app="EmpApp">
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="@Url.Content("~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/angular.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/angular-route.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/app/app.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/app/controller.js")" type="text/javascript"></script>
</head>
<body>
<div class="main container" ng-view>
</div>
</body>
</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:
var EmpApp = angular.module('EmpApp', [
'ngRoute',
'EmpControllers'
]);
EmpApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/list', {
templateUrl: 'Employee/list.html',
controller: 'ListController'
}).
when('/create', {
templateUrl: 'Employee/edit.html',
controller: 'EditController'
}).
when('/edit/:id', {
templateUrl: 'Employee/edit.html',
controller: 'EditController'
}).
when('/delete/:id', {
templateUrl: 'Employee/delete.html',
controller: 'DeleteController'
}).
otherwise({
redirectTo: '/list'
});
}]);
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.
a) List.html
<div>
<a href="#/create" class="btn">Create</a>
</div>
<div class="table-responsive">
<table class="table table-striped table-bordered">
<tr>
<th>Employee Id</th>
<th>First Name</th>
<th>Last Name</th>
<th>Description</th>
<th>Salary</th>
<th>Country</th>
<th>State</th>
<th>Date of Birth</th>
<th>Is Active</th>
<th></th>
<th></th>
</tr>
<tr ng-repeat="item in employees">
<td>{{ item.EmployeeId }}</td>
<td>{{ item.FirstName }}</td>
<td>{{ item.LastName }}</td>
<td>{{ item.Description }}</td>
<td>{{ item.Salary | number: 2 }}</td>
<td>{{ item.Country }}</td>
<td>{{ item.State }}</td>
<td>{{ item.DateofBirth | date }}</td>
<td>
<span class="label" ng-class="{true:'label-success', false:'label-danger', '':'hidden'}[item.IsActive]">
{{ item.IsActive ? 'Active' : 'In Active' }}</span>
</td>
<td>
<a href="#/edit/{{item.EmployeeId}}" class="glyphicon glyphicon-edit"></a>
</td>
<td>
<a href="#/delete/{{item.EmployeeId}}" class="glyphicon glyphicon-trash"></a>
</td>
</tr>
</table>
</div>
b) Edit.html
<h3>
{{ title }}</h3>
<hr />
<form role="form" style="max-width: 500px;">
<strong class="error">{{ error }}</strong>
<div class="form-group">
<label for="firstname">
First Name</label>
<input type="text" class="form-control" id="firstname" ng-model="firstname" />
</div>
<div class="form-group">
<label for="lastname">
Last Name:</label>
<input type="text" class="form-control" id="lastname" ng-model="lastname" />
</div>
<div class="form-group">
<label for="country">
Country:</label>
<select class="form-control" id="country" ng-model="country" ng-options="c.Value as c.Text for c in countries" ng-change="getStates()">
<option value="">-- Select Country --</option>
</select>
</div>
<div class="form-group">
<label for="state">
State:</label>
<select class="form-control" id="state" ng-model="state" ng-disabled="!states" ng-options="s.Value as s.Text for s in states">
<option value="">-- Select State --</option>
</select>
</div>
<div class="form-group">
<label for="salary">
Current Salary:</label>
<input type="text" class="form-control" id="salary" ng-model="salary" />
</div>
<div class="form-group">
<label for="dob">
Date of Birth:</label>
<input type="date" class="form-control" id="dob" ng-model="dob" />
</div>
<div class="form-group">
<label for="description">
Description:</label>
<textarea rows="5" cols="10" class="form-control" id="description" ng-model="description"></textarea>
</div>
<div class="form-group checkbox">
<label>
<input type="checkbox" ng-model="active" />Active</label>
</div>
<a href="#/list" class="btn btn-info">Back to List</a>
<button type="submit" class="btn btn-default" ng-click="save()">
Submit</button>
</form>
c) Delete.html
<h3>
Are you want to sure to delete this record?</h3>
<hr />
<form class="form-horizontal" style="max-width: 500px;">
<div class="form-group">
<label class="control-label col-xs-3">
First Name :</label>
<div class="col-xs-9">
<p class="form-control-static">
{{ firstname }}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-3">
Last Name :</label>
<div class="col-xs-9">
<p class="form-control-static">
{{ lastname }}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-3">
Country :</label>
<div class="col-xs-9">
<p class="form-control-static">
{{ country }}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-3">
State :</label>
<div class="col-xs-9">
<p class="form-control-static">
{{ state }}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-3">
Salary :</label>
<div class="col-xs-9">
<p class="form-control-static">
{{ salary }}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-3">
Date of Birth :</label>
<div class="col-xs-9">
<p class="form-control-static">
{{ dob | date }}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-3">
Description :</label>
<div class="col-xs-9">
<p class="form-control-static">
{{ description }}</p>
</div>
</div>
<div class="form-group">
<div class="col-xs-offset-3 col-xs-9">
<span class="label" ng-class="{true:'label-success', false:'label-danger', '':'hidden'}[active]">
{{ active ? 'Active' : 'In Active' }}</span>
</div>
</div>
<div class="form-group">
<div class="col-xs-offset-3 col-xs-9 text-center">
<a href="#/list" class="btn btn-info">Back to List</a>
<button type="submit" class="btn btn-primary" ng-click="delete()">
Delete</button>
</div>
</div>
</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:
var EmpControllers = angular.module("EmpControllers", []);
// this controller call the api method and display the list of employees
// in list.html
EmpControllers.controller("ListController", ['$scope', '$http',
function ($scope, $http) {
$http.get('/api/employee').success(function (data) {
$scope.employees = data;
});
} ]
);
// this controller call the api method and display the record of selected employee
// in delete.html and provide an option for delete
EmpControllers.controller("DeleteController", ['$scope', '$http', '$routeParams', '$location',
function ($scope, $http, $routeParams, $location) {
$scope.id = $routeParams.id;
$http.get('/api/employee/' + $routeParams.id).success(function (data) {
$scope.firstname = data.FirstName;
$scope.lastname = data.LastName;
$scope.country = data.Country;
$scope.state = data.State;
$scope.salary = data.Salary;
$scope.active = data.IsActive;
$scope.dob = data.DateofBirth;
$scope.description = data.Description;
});
$scope.delete = function () {
$http.delete('/api/Employee/' + $scope.id).success(function (data) {
$location.path('/list');
}).error(function (data) {
$scope.error = "An error has occured while deleting employee! " + data;
});
};
}
]);
// this controller call the api method and display the record of selected employee
// in edit.html and provide an option for create and modify the employee and save the employee record
EmpControllers.controller("EditController", ['$scope', '$filter', '$http', '$routeParams', '$location',
function ($scope, $filter, $http, $routeParams, $location) {
$http.get('/api/country').success(function (data) {
$scope.countries = data;
});
$scope.id = 0;
$scope.getStates = function () {
var country = $scope.country;
if (country) {
$http.get('/api/country/'+country).success(function (data) {
$scope.states = data;
});
}
else {
$scope.states = null;
}
}
$scope.save = function () {
var obj = {
EmployeeId: $scope.id,
FirstName: $scope.firstname,
LastName: $scope.lastname,
Country: $scope.country,
State: $scope.state,
Salary:$scope.salary,
IsActive: $scope.active,
Description: $scope.description,
DateofBirth: $scope.dob
};
if ($scope.id == 0) {
$http.post('/api/Employee/', obj).success(function (data) {
$location.path('/list');
}).error(function (data) {
$scope.error = "An error has occured while adding employee! " + data.ExceptionMessage;
});
}
else {
$http.put('/api/Employee/', obj).success(function (data) {
$location.path('/list');
}).error(function (data) {
console.log(data);
$scope.error = "An Error has occured while Saving customer! " + data.ExceptionMessage;
});
}
}
if ($routeParams.id) {
$scope.id = $routeParams.id;
$scope.title = "Edit Employee";
$http.get('/api/employee/' + $routeParams.id).success(function (data) {
$scope.firstname = data.FirstName;
$scope.lastname = data.LastName;
$scope.country = data.Country;
$scope.state = data.State;
$scope.salary = data.Salary;
$scope.active = data.IsActive;
$scope.description = data.Description;
$scope.dob = new Date(data.DateofBirth);
$scope.getStates();
});
}
else {
$scope.title = "Create New Employee";
}
}
]);
In this controller.js we have multiple controller 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 all we have implement 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 which motivates me for writing articles.
43 comments:
Do you have the source code for this project I'm running into many errors and problems with the Employee class
ie:
1:"Database.SetInitializer(new EmployeeDbContextInitializer());"
"Database.SetInitializer" says thats a virtual member call in constructor
2:"public class EmployeeDbContextInitializer : DropCreateDatabaseIfModelChanges" the Visula Studio says "Cannot resolve symbol DropCreateDatabaseIfModelChanges"
3: "protected override void Seed(EmployeeDbContext context)" Visual Studio Says:"There is no suitable method for override"
becasue of that I also get this problem
" base.Seed(context);" the Visula Studio says "Cannot resolve symbol"
The whole code is given in article itself. You can copy step by step.
Hi Rohit Kesharwani..
nice article, it gave me a lot knowledge, because i'm on learning about angularjs, mvc, and web api ^^.
But, better if you can share the full project,so programmer or people which are still newbie (like me :D) can see the detail and test to run the application.
It will make more learn faster i think..
Appreciate if you could update it.
thanks and cheers,
Ok. I will send you a link by today itself after uploading on server.
Could you please give a link to source code?
Ok. I will do.
Hi Rohit Kesharwani..
nice article, it gave me a lot knowledge, because i'm on learning about angularjs, mvc, and web api ^^.
But, better if you can share the full project,so programmer or people which are still newbie (like me :D) can see the detail and test to run the application.
It will make more learn faster i think..
Appreciate if you could update it.
thanks and cheers,
Download source code from here:
https://onedrive.live.com/?cid=a9f5007cd218e84f&id=A9F5007CD218E84F%21137&authkey=!AJ9tpQLeOWGVPDU
Thank you for the lesson and the code. Great job.
I knew about you from here: http://www.codeproject.com/Articles/832288/CRUD-with-SPA-ASP-NET-Web-API-and-Angular-js
I faced some problems there.
Thanks a lot! Great job
Hi Rohit,
There is an error when i attach my database in connectionstring and give table Name to Employee and it gives error that An exception of type 'System.NotSupportedException' occurred in EntityFramework.dll but was not handled in user code
Hi Maulin,
You do not need to create database and table, this application will create automatically because it is using code first approach. You just need to change data source, user id and password in connection string.
If you already created it database and Employee table then map datatype and column of your database table with Employee class.
You can download source code and check:
https://onedrive.live.com/?cid=a9f5007cd218e84f&id=A9F5007CD218E84F%21137&authkey=!AJ9tpQLeOWGVPDU
i did everything as u have given but its not reading data. its giving this output
Create
Employee Id First Name Last Name Description Salary Country State Date of Birth Is Active
{{ item.EmployeeId }} {{ item.FirstName }} {{ item.LastName }} {{ item.Description }} {{ item.Salary | number: 2 }} {{ item.Country }} {{ item.State }} {{ item.DateofBirth | date }} {{ item.IsActive ? 'Active' : 'In Active' }}
Hi akhilesh,
You can download source code and rectify your mistake:
https://onedrive.live.com/?cid=a9f5007cd218e84f&id=A9F5007CD218E84F%21137&authkey=!AJ9tpQLeOWGVPDU
Thank you Rohit Kesharwani , good articular i learn easily through this blog .....
can u tell me how to do "Search Sort and Pagination" on List
Thanks Rafi.
Article of Search, Sort and Pagination is given below:
http://rohit-developer.blogspot.in/2015/01/sorting-paging-and-filter-grid-using.html
Hi Rohit I have followed your steps but EmployeeDbContext which i have defined in Employee class in model folder is not recognized in Employee Controller although I have added using system .data. entity in EmployeeController but still its giving an error that "EmployeeDbContext could not be found ....Please Help me Out
I am not getting any error now but its giving a blank page out put when I run it . can u tell what mistake I am making???
Is EmpDb database is created in SQL Server?
You can download source code also in order to find your mistake.
https://onedrive.live.com/?cid=a9f5007cd218e84f&id=A9F5007CD218E84F%21137&authkey=!AJ9tpQLeOWGVPDU
Good article i loved it,I downloaded code run the solution in VS2015,It working good but while create record it not taking Date field input in Microsoft edge browser.I am new to AngularJS could you please guide how to dugug the application
hello rohit Kesharwani this article are very good for the AngularJS WebApi using crud oprations.But please give the full demo with source code..
hello rohit kesharwani i have tried this article followed all the step but last run the my demo i have got the one error...not load the partial view contain in index page...so please help me..any one..then debugger the code so i have got the error in app.js file..direct redirect to
otherwise({
redirectTo: '/list'
});
this section..and not show my list of the product table...so please help me any one...
Hi Hiren,
you can download source code from here:
https://onedrive.live.com/?cid=a9f5007cd218e84f&id=A9F5007CD218E84F%21137&authkey=!AJ9tpQLeOWGVPDU
Thanks & Regards,
Rohit
hi Rohit Kesharwani,Thanks for the given me your source code..your article are very good for the knowledge of angularJS..
Excellent information with unique content and it is very useful to know about the information based on blogs.
Hire Angular Developers
Hi Rohit, This article cleared my concept.
hi Rohit ,
this article is code first approach. do you have same article in DB first approach. as you know we create the application from scratch but we can not change our DB in that case its become difficult to use existing db.
hi Rohit ,
this article is awesome so id like to be able to get to do the same thing,
im trying to find the source code in the link you posted but i cant, wich of the files is it?
thanx
Hi Dave blulls,
Thanks, you can find by using below link:
https://onedrive.live.com/?cid=a9f5007cd218e84f&id=A9F5007CD218E84F%21137&authkey=!AJ9tpQLeOWGVPDU
Thanks for the fast respond :)
Thanks for this awesome tutorial. I have read somewhere that it's not a best practices to have Controller per view, and that controllers must be unique per entity.
what's the best practices to structure controller ?
thansk for your help
HI Rohit
Awesome article..really i got confidence on using crud operation using web api..
great job
Thank you
Hello,
In list.html, i trying to edit the data of employee.
when i click the edit button it's redirecting to the edit controller rather it's going to listcontroller itself.
What's your thought regarding the issue.
Thank you for making the effort and spreading this information with all of us. It was indeed very useful and informative! Learn more about big data consultants.
Nice post . Thanks for the shearing valuable information. I really fiend this type blog. Special thanks to writer.
Hire Angularjs Developer
I can't find/access source code on given link. Please, help!
Tom
Really Good blog post. provided a helpful information.I hope that you will post more updates like this AngularJS Online Training Bangalore
Good Post. I like your blog. Thanks for Sharing...........................!!!
AngularJs Training in Noida
Great Content. It will useful for knowledge seekers. Keep sharing your knowledge through this kind of article.
MVC Training in Chennai
MVC Classes in Chennai
Excellent article and with lots of information. I really learned a lot here. Do share more like this.
Benefits Of Web Designing
Advantages Of Web Designing
Such a very useful article. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article.
Java Vogue
phab
Post a Comment