DotNetCurry Logo

CRUD Operations using ASP.NET Web API and Angular.js

Posted by: Mahesh Sabnis , on 10/22/2014, in Category ASP.NET
Views: 206358
Abstract: The AngularJS framework provides some cool features for developing MVC based applications using HTML. In this article, we will use AngularJS and ASP.NET Web API to create an application that pulls data from a database and performs CRUD Operations.

AngularJS is one of the most popular client-side frameworks on the web. It is maintained by Google and helps in creating Single-Page Applications using HTML, CSS and JavaScript. This framework provides Model-View-Controller (MVC) on the client side and helps the developer to implement structural JavaScript on client-side. The Data-Binding and Dependency Injection features provided by Angular simplifies the heavy and complex JavaScript code on the client, which we used to write earlier to do the same task. If you are absolutely new to AngularJS, you can get some additional information over here.

In this article, we will make use of ASP.NET MVC WEB API and AngularJS to develop an application for performing CRUD operations. We will use the following features of AngularJS in our application:

 

DataBinding: This provides an automatic synchronization of data in between data model and the User interface components. This synchronization is managed in such a way that when any changes occur in either Model or View, it is notified to one another.

Module: Acts as a container for different components of the application e.g. Controller, Services, directives, etc. The bootstrapping of the application is specified by the Module. This is attached with DOM using ng-app directive.

Controller: Controller is a repository for the actions to be exposed to the DOM. This is a JavaScript constructor function attached to the DOM using ng-controller directive. When the controller is attached with DOM a new injectable scope parameter will be available to the controller’s constructor function of the name $scope.

Services: Component to act as a repository for the code to be shared across the application. Generally we can make use of it to define external services call from Angular application.

Some Angular Directives used in the Application

Directives add capability of extending HTML. They are the most complex and the most important part of AngularJS. Here are some built-in directives used in this application:

· ng-app: used to auto bootstrap the AngularJS application. This is typically applied to the root of HTML document e.g. , .

· ng-controller: used to attach the controller class to the view. This helps to expose the action methods and the scope model from the controller to be accessible to view.

· ng-model: used to bind the scope model declared in the controller to the UI elements e.g. input, select,etc.

· ng-repeat: used to instantiate the template for each item in the source collection received from the scope of the controller.

· ng-click: executes the action method form the controller class when the element on the View is clicked.

Read more about the various built-in Angular Directives over here.

The AngularJS & Web API Implementation

Step 1: Open Visual Studio 2013 (for this article VS2013 Ultimate with Update 3 is used) and create a new Empty MVC project. Name this project as ‘A6_Performing_CRUD_Using_Angular’.

Step 2: In the project, right-click on the App_Data folder and add a new Sql Server Database of the name ‘Application.mdf’. In this database add a new table with the name Employee having the following schema:

CREATE TABLE [dbo].[Employee] (
    [EmpNo]       INT           IDENTITY (1, 1) NOT NULL,
    [EmpName]     VARCHAR (100) NOT NULL,
    [Salary]      INT           NOT NULL,
    [DeptName]    VARCHAR (50)  NOT NULL,
    [Designation] VARCHAR (50)  NOT NULL,
    PRIMARY KEY CLUSTERED ([EmpNo] ASC)
);

Add some sample data to this table.

Step 3: In the Models folder, to create models, we need to add a new ADO.NET Entity Data model. Select the Application.mdf in the Entity Framework wizard and select Employee table. After completing the wizard, the table mapping will be as below:

employee-model

Step 4: We need to add the WEB API controller in MVC so that we can get methods for performing CRUD operations. Right-Click on the Controllers folder, add new Controller and select ‘WEB API 2 Controller with actions, using Entity Framework’ as shown here:

webapi-scaffold

Step 5: Name the API controller as EmployeesAPIController. Set the Model class and Data Context class as shown here:

employee-api-controller

Step 6: Right-Click on the Controllers folder and add an Empty MVC controller of the name ‘EmployeeController’. This will add a controller with an Index action method in it. Scaffold the Empty View of name ‘Index.cshtml’ from the Index method.

Step 7: We need to add AngularJS to the current project. To do so, right-click on the project name and select ‘Manager NuGet Package’. From the Package Nuget Manager Window search for AngularJS as shown below and add it to the current project:

angularjs-project

This will add Angular scripts in the scripts folder of the project.

Step 8: In the Scripts folder, add new folder and add 3 new JavaScript files in it. Name them Module.js, Service.js and Controller.js.

Module.js

/// 
var app;
(function () {
    app = angular.module("crudModule", []);
})();

The above code defines module of name ‘crudModule’. This will be used as Bootstrapper for the application and will be exposed to view using ng-app directive.

Service.js

/// 
/// 


app.service('crudService', function ($http) {

    
    //Create new record
    this.post = function (Employee) {
        var request = $http({
            method: "post",
            url: "/api/EmployeesAPI",
            data:  Employee
        });
        return request;
    }
    //Get Single Records
    this.get = function (EmpNo) {
       return $http.get("/api/EmployeesAPI/" + EmpNo);
    }

    //Get All Employees
    this.getEmployees = function () {
        return $http.get("/api/EmployeesAPI"); 
    }


    //Update the Record
    this.put = function (EmpNo, Employee) {
        var request = $http({
            method: "put",
            url: "/api/EmployeesAPI/" + EmpNo,
            data: Employee
        });
        return request;
    }
    //Delete the Record
    this.delete = function (EmpNo) {
        var request = $http({
            method: "delete",
            url: "/api/EmployeesAPI/" + EmpNo
        });
        return request;
    }
});

The above is the AngularJS service component with $http as dependency. This is used to make an external call to the WEB API using $http’s get, post, put and delete methods to perform CRUD operations.

$http is Angular’s wrapper around XmlHttpRequest. It provides a set of high level APIs and a low level API to talk to REST services. Each of the API methods return $q promise object. Following are the APIs exposed by $http:

  • $http.$get(url): Sends an HTTP GET request to the URL specified
  • $http.post(url, dataToBePosted): Sends an HTTP POST request to the URL specified
  • $http.put(url, data): Sends an HTTP PUT request to the URL specified
  • $http.patch(url, data): Sends an HTTP PATCH request to the URL specified
  • $http.delete(url): Sends an HTTP DELETE request to the URL specified

Controller.js

It may include some additional details about $http. For example, you may say it is a wrapper around XmlHttpRequest object and brief about the shorthand methods it contains to perform HTTP operations.

/// 


/// 
 
//The controller is having 'crudService' dependency.
//This controller makes call to methods from the service 
app.controller('crudController', function ($scope, crudService) {
   
    $scope.IsNewRecord = 1; //The flag for the new record

    loadRecords(); 

    //Function to load all Employee records
    function loadRecords() {
        var promiseGet = crudService.getEmployees(); //The MEthod Call from service

        promiseGet.then(function (pl) { $scope.Employees = pl.data },
              function (errorPl) {
                  $log.error('failure loading Employee', errorPl);
              });
    }
    
    //The Save scope method use to define the Employee object.
    //In this method if IsNewRecord is not zero then Update Employee else 
    //Create the Employee information to the server
    $scope.save = function () {
        var Employee = {
            EmpNo: $scope.EmpNo,
            EmpName: $scope.EmpName,
            Salary: $scope.Salary,
            DeptName: $scope.DeptName,
            Designation: $scope.Designation
        };
        //If the flag is 1 the it si new record
        if ($scope.IsNewRecord === 1) {
            var promisePost = crudService.post(Employee);
            promisePost.then(function (pl) {
                $scope.EmpNo = pl.data.EmpNo;
                loadRecords();
            }, function (err) {
                console.log("Err" + err);
            });
        } else { //Else Edit the record
            var promisePut = crudService.put($scope.EmpNo,Employee);
            promisePut.then(function (pl) {
                $scope.Message = "Updated Successfuly";
                loadRecords();
            }, function (err) {
                console.log("Err" + err);
            });
        }

        
            
    };

    //Method to Delete
    $scope.delete = function () {
        var promiseDelete = crudService.delete($scope.EmpNo);
        promiseDelete.then(function (pl) {
            $scope.Message = "Deleted Successfuly";
            $scope.EmpNo = 0;
            $scope.EmpName = "";
            $scope.Salary = 0;
            $scope.DeptName = "";
            $scope.Designation = "";
            loadRecords();
        }, function (err) {
            console.log("Err" + err);
        });
    }

    //Method to Get Single Employee based on EmpNo
    $scope.get = function (Emp) {
        var promiseGetSingle = crudService.get(Emp.EmpNo);

        promiseGetSingle.then(function (pl) {
            var res = pl.data;
            $scope.EmpNo = res.EmpNo;
            $scope.EmpName = res.EmpName;
            $scope.Salary = res.Salary;
            $scope.DeptName = res.DeptName;
            $scope.Designation = res.Designation;

            $scope.IsNewRecord = 0;
        },
                  function (errorPl) {
                       console.log('failure loading Employee', errorPl);
                  });
    }
    //Clear the Scopr models
    $scope.clear = function () {
        $scope.IsNewRecord = 1;
        $scope.EmpNo = 0;
        $scope.EmpName = "";
        $scope.Salary = 0;
        $scope.DeptName = "";
        $scope.Designation = "";
    }
});

The above controller has the $scope and crudService as its dependency. The $scope is used to define Models which will be exposed to View for DataBinding. The controller makes call to the service for performing CRUD operations. All these functions makes use of the ‘Promise’ object, which is used to monitor asynchronous progress. The promise will successfully return the data from the service when the function from service completes its call to external service. Following are the functions defined by the controller class:

· loadRecords - getEmployees() function of the service to read all employees.

· Save - This is the scope function used to Add/Edit record based upon the IsNewRecord flag.

· Delete - The scope function to delete the record.

· Get - The scope function to get Employee based upon the id.

· Clear - The scope function to clear all scope model declarations.

Step 9: Open the Index.cshtml, which we created in Step 6 and add the following Markup with DataBinding using AngularJs.


@{
    ViewBag.Title = "Index";
}


    

    

Using Angular for Performing CRUD Operations

EmpNo
EmpName
Salary
DeptName
Designation
{{Message}}
EmpNo EmpName Salary DeptName Designation
{{Emp.EmpNo}} {{Emp.EmpName}} {{Emp.Salary}} {{Emp.DeptName}} {{Emp.Designation}}

The above HTML markup has the following features:

· The is bound with the ‘crudModule’ using ng-app directive. This specifies that the Module with its contents e.g. Controller will be used in the bootstrap.

· The

with id ‘tblContainer’ is bound with the ‘crudController’ using ng-controller directive. This means that the declarations in the controller e.g. scope Models and functions will be available for the contents of the
.

· The

with id ‘tblCRUD’ contains elements of the type ‘button’ and textboxes. Textboxes are bound with the scope models for Employee properties e.g. EmpNo, EmpName, Salary, DeptName and Designation using ng-Model directive. Buttons are bound with the functions from the controller using ng-click directive.

· The

with id as ‘tblCollections’ contains which is bound with the Employees scope collection using ng-repeat directive. This iterates through the Employees collection and displays its contents in elements inside the
elements using ‘{{}}’ bind syntax.

Run the application.

The page will appear as shown below:

angularjs-demo

The above figure shows all Employee records in the Table.

Enter Data in the Textboxes except EmpNo and click on the ‘Save’ button. The data will be Saved, the EmpNo will be generated and displayed in the EmpNo Textbox and the Employee Table will be refreshed as shown here:

angularjs-webapi-demo

Click on the ‘New’ button which will clear all textboxes. Click on any row of the table and the selected record will be displayed in the Textboxes. Similarly Edit and Delete operations can be tested.

Conclusion: The AngularJS framework provides some cool features for developing MVC based applications using HTML.  Modules, Controller and Services helps to implement a modular approach for application development on the client-side.

Download the entire source code of this article (Github)

Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+
Further Reading - Articles You May Like!
Author
Mahesh Sabnis is a DotNetCurry author and Microsoft MVP having over 17 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). Follow him on twitter @maheshdotnet


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by George on Friday, October 24, 2014 12:45 PM
Your source code does not contain all the code. The js scripts you created are missing.
Comment posted by Tom Z on Friday, October 24, 2014 1:12 PM
Hi Mahesh,
The download zip at GitHub does not seem to include custom js files and cshtml files.
Thanks,
Tom
Comment posted by Carol on Saturday, October 25, 2014 7:58 AM
@George @Tom Z - Apologies. The code has been updated. Thanks for letting us know.
Comment posted by Nicolas on Sunday, October 26, 2014 6:28 AM
I've try it from scratch, works perfectly.
Great tutorial, thanks for sharing.
Comment posted by Mahesh Sabnis on Thursday, October 30, 2014 2:41 AM
Hi Nicolos,

Thanks a lot.
Regards
Mahesh Sabnis
Comment posted by sriram on Monday, November 3, 2014 2:39 PM
thank you very much for sharing the code.Its helps me alot for quick start.

You are helping a lot.
Comment posted by Christos on Tuesday, November 4, 2014 6:17 AM
You didn't mention that this line should be added to Global.asax.cs

GlobalConfiguration.Configure(WebApiConfig.Register);

Otherwise the api is not working.

Thanks for the tutorial
Comment posted by Christos on Tuesday, November 4, 2014 6:26 AM
You didn't mention that this line should be added to Global.asax.cs

GlobalConfiguration.Configure(WebApiConfig.Register);

Otherwise the api is not working.

Thanks for the tutorial
Comment posted by ajru on Thursday, November 6, 2014 7:06 AM
Describe about of JSAs in asp.net Use
Comment posted by Filipe on Friday, November 7, 2014 8:26 AM
Thanks Christos for the Global.asax info!
Comment posted by Makbul Syed on Sunday, November 9, 2014 4:16 AM
Nice post. Thank you for sharing.
Comment posted by MAhesh Sabnis on Tuesday, November 11, 2014 3:02 AM
Hi All,

Since the MVC5 application is created using VS2013, the Empty project is created with MVC and WEB API checkboxes selected, so the Global.asax entry for the WEB API confifuration is already available in the template.
Thanks
Mahesh Sabnis  
Comment posted by Matt Slay on Monday, November 17, 2014 12:06 AM
Thank you for taking the time to create this nice intro. It is easy to follow.

I am curious about the pattern of hosting every field of the Employee object as a separate property on the $scope, rather than simply storing the entire Employee object, as in $scope.Employee

In the get() controller method, you would just store:
  $scope.Employee = pl.data;

Then, your ng-model property for each field in the UI would be Employee.EmpName, Employee.Salary, etc.

I'm not saying your way is wrong. I just like to go ahead and store the entire Employee object, rather that micro-mapping each field.
Comment posted by Klaus on Tuesday, November 18, 2014 5:02 AM
Matt both approaches are correct. Your is better but assumes higher level of understanding of programming. The way author presented is good for begineers.

Sorry for bad English. I am German.
Comment posted by Kabs on Sunday, December 7, 2014 10:51 PM
I've try it from scratch, works perfectly.
Great tutorial, thanks for sharing.
if you have any other tutorial related to MVC or other than please share it.
Comment posted by zxczxc on Monday, January 5, 2015 6:03 AM
sxcsxcz
Comment posted by Prakash on Monday, January 5, 2015 6:05 AM
nice but not so clear we need step by step for mvc application.
Comment posted by Rohit Kesharwani on Friday, January 9, 2015 11:50 PM
Nice article. I also written an article on the same topic I hope it also helps the user.

http://rohit-developer.blogspot.in/2015/01/crud-using-mvc-web-api-and-angularjs.html

Thanks.
Keep writing and motivate us for doing the same.
Comment posted by Jay Mehta on Friday, January 23, 2015 5:22 AM
Superb Article Sir... :)

Thanks
Comment posted by Anupam on Monday, January 26, 2015 12:21 PM
Very useful article Mahesh , Thanks for sharing.
Comment posted by Mohammed Ansari on Friday, January 30, 2015 12:59 AM
Your article is very good sir, but it is difficult to understand whole at once in the beginning, will it be possible for you to create a video of creating this. Thank you so much
Comment posted by MAhesh Sabnis on Wednesday, February 4, 2015 12:24 AM
Hi All,
  Thanks a lot.
Regards
Mahesh Sabnis
Comment posted by b.rochdi on Friday, February 6, 2015 4:36 AM
Hi, Thank's for this nice tuto.
I have a question How I can create controller with action .....
I haven't this item choice in my Scaffolded Item add
thks!
Comment posted by Hebtech on Thursday, February 12, 2015 11:32 PM
Well done. Appreciate the time that you put into this.
Comment posted by Anil Singh on Thursday, February 19, 2015 11:51 PM
Awesome post!!!

It might help you!!
http://www.code-sample.com/2014/09/angularjs-documentation.html
Comment posted by S Rehman Ali on Friday, February 20, 2015 7:41 AM
that's really something that compel me to say thumbs up man! for this good effort.. simple nice and decent.. keep it up..
Comment posted by Abhi on Thursday, March 19, 2015 7:00 AM
//The controller is having 'crudService' dependency.
//This controller makes call to methods from the service
app.controller('crudController', function ($scope, crudService)

I'm new to Angular. Cosidering above code, I want to understand how the 'crudService' is passed to controller where there is no reference of "Service.js" have included.
Comment posted by Tushar Gupta on Monday, March 23, 2015 1:15 AM
i am so impressed with this articles. i am beginner in angular.js and this article clear basic concept of angular.js
Comment posted by Aj on Tuesday, March 24, 2015 2:54 AM
Good post!!

For more details about AngularJS:
http://www.techstrikers.com/AngularJS/angularjs-tutorials.php
Comment posted by Prashanth Kumar Mangipudi on Tuesday, March 31, 2015 7:35 AM
Mahesh sir,

This article is great one. I have learned a lot from it.

Thanks
Prashanth Mangipudi
Comment posted by Laura Gonzalez on Tuesday, March 31, 2015 4:32 PM
Hi
Thanks for your post, I can use get and getall, but can't post, delete or put, the service accepts json. do I need to transform the request?

Thanks
Comment posted by mm on Sunday, April 5, 2015 8:58 AM
fdffdf
Comment posted by Ajay Bhingare on Wednesday, April 8, 2015 4:33 PM
Good One Mahesh :)
Comment posted by Satyanarayana Rao on Thursday, April 9, 2015 8:20 PM
Excellent article. It is very useful to every .net developer
Comment posted by Shrikant Patil on Friday, April 24, 2015 6:31 AM
Great article.

Just have one question, Can somebody please explain what the below line of code do:
ng-click ="get(Emp)"

Thanks.
Comment posted by waseem saleem on Friday, April 24, 2015 12:23 PM
I follow the tutorial but angularjs not work.I searched it but I could not solve it.Please guide me.I'm new in AngularJS
Comment posted by Kishor on Thursday, April 30, 2015 12:51 PM
Great tutorial, Very much useful.
Thank you Mahesh.
Comment posted by noushad on Tuesday, May 5, 2015 6:57 AM
sir, I follow the tutorial but I am copied the crud code to my different application. I am able to create a new record .but what dosn't work is "Click on any row of the table and the selected record will be displayed in the Textboxes"

I am downloaded the code from the github it works good, but my application is not working. don't know what is missing from my application. Please reply...
Comment posted by Rajesh on Thursday, May 21, 2015 6:12 AM
Hi Suresh,
Thanks for your nice article. I've implemented all from the scratch what you explained, but still am getting

ailure loading Employee Object {data: "<!DOCTYPE html>
↵<html>
↵    <head>
↵        <titl…nStep step, Boolean& completedSynchronously)
↵-->", status: 404, headers: function, config: Object, statusText: "Not Found"}

please correct me where am wrong.
Comment posted by Rajesh on Thursday, May 21, 2015 6:13 AM
Sorry, in my above post something was missing

GET http://localhost:9396/api/EmployeesAPI 404 (Not Found)

above is the actual error am getting.