Introduction
Before this article, we have done many examples using AngularJS like, fetch & display data from a database, create simple registration form with validation, Implement AngularJS routing any much more. But till now we have not created any complete application. Today I will show you how to create a very simple application using AngularJS in asp.net MVC.Here in this part, I will try to make our application as simple as possible and later we will enhance this application part by part for making the article easy to understand.
If you want to create simple contact book application using ASP.NET MVC, please visit CONTACT BOOK APP USING ASP.NET MVC
Here I am going to create a very simple Contact Book application. For making this application simple and understandable, here we will create a very simple form for save contact information to the database, a simple listing page for fetch contacts data from database and display in a table and will implement AngularJS routing for make this application a SPA application.
Later we will add more featured part by part.
Just follow the following steps in order to implement "Part 1 - Simple Contact Book application in AngularJS".
Step - 1: Create New Project.
Step-2: Add a Database.
Step-3: Create a table.
Step-4: Add Entity Data Model.
A popup window will come (Entity Data Model Wizard) > Select Generate from database > Next >
Chose your data connection > select your database > next > Select tables > enter Model Namespace > Finish.
Step-5: Create an MVC Controller.
Here I have created a controller named "HomeController"
Step-6: Add an MVC action.
Here I have added "Index" Action to "Home" Controller. Please write this following codepublic ActionResult Index() { return View(); }
Step-7: Add view for that(here Index action) action.
Right Click on Action Method (here right click on Index action) > Add View... > Enter View Name > Select "Empty" under Template dropdown > > Add.HTML Code
@{ ViewBag.Title = "Index"; } <h2>Index</h2>
Step-8: Add an another action for fetch contact list from our database.
public JsonResult GetContacts() { List<Contact> contactList = new List<Contact>(); using (MyDatabaseEntities dc = new MyDatabaseEntities()) { contactList = dc.Contacts.OrderBy(a => a.ContactName).ToList(); } return new JsonResult { Data = contactList, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; }
Step-9: Add an another action for single contact data from database by contact id.
In this action, we will fetch single contact data from database by contact id, which is required for open edit form with data.public JsonResult GetContact(int contactID) { Contact contact = null; using (MyDatabaseEntities dc = new MyDatabaseEntities()) { contact = dc.Contacts.Where(a => a.ContactID.Equals(contactID)).FirstOrDefault(); } return new JsonResult { Data = contact, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; }
Step-10: Add an another action for save (add/update) contact information to the database.
[HttpPost] public JsonResult SaveContact(Contact contact) { bool status = false; string message = ""; try { if (ModelState.IsValid) { using (MyDatabaseEntities dc = new MyDatabaseEntities()) { if (contact.ContactID > 0) { //Update var c = dc.Contacts.Where(a => a.ContactID.Equals(contact.ContactID)).FirstOrDefault(); if (c != null) { c.ContactName = contact.ContactName; c.ContactNo = contact.ContactNo; c.EmailID = contact.EmailID; c.Address = contact.Address; } } else { //create dc.Contacts.Add(contact); } dc.SaveChanges(); status = true; } } } catch (Exception ex) { message = ex.Message; } return new JsonResult { Data = new { status = status, message = message } }; }
Step-11: Add an another action for delete contact from the database.
[HttpPost] public JsonResult DeleteContact(int contactID) { bool status = false; string message = ""; try { using (MyDatabaseEntities dc = new MyDatabaseEntities()) { var v = dc.Contacts.Where(a => a.ContactID.Equals(contactID)).FirstOrDefault(); if (v != null) { dc.Contacts.Remove(v); dc.SaveChanges(); status = true; } } } catch (Exception ex) { message = ex.Message; } return new JsonResult { Data = new { status = status, message = message } }; }
Step-12: Add AangularJS library in our application.
Go to solution explorer > Right click on project name > Manage NuGet packages > Search for angularjs > install AngularJS Core and AngularJS route > click on close button.
Step-13: Do following (see below image) folder structure for angular conponents
You can see here I have added following folders inside Scripts folder- ngComponents
- ngConfigs - This is for all the files where we will write configuration code ex. routing
- ngControllers - This is for angular controllers js files
- ngServices - This is for angular services js files
- ngTemplates -This is for angular templates files
Step-14: Add a javascript file in the ngConfig folder and write below code.
Go to solution explorer > Right click on ngConfigs folder (inside Scripts > ngComponents) > Add > New Item > Select javascript file under Scripts > enter file name > Click on Add button.
var app = angular.module('myContactBook', ['ngRoute']); app.config(['$routeProvider', '$locationProvider', '$httpProvider', function ($routeProvider, $locationProvider, $httpProvider) { //Start routing $routeProvider .when('/home', { templateUrl: '/Scripts/ngComponents/ngTemplates/home.html', controller : 'homeController' }) .when('/savecontact/:id', { templateUrl: '/Scripts/ngComponents/ngTemplates/savecontact.html', controller: 'saveContactController' }) .when('/', { redirectTo: function () { return '/home'; } }) .when('/error', { templateUrl: '/Scripts/ngComponents/ngTemplates/error.html', controller : 'errorController' }) $locationProvider.html5Mode(false); //End routing //configure http post method $httpProvider.defaults.headers.post = { 'content-type': 'application/json' } //Erroe handling $httpProvider.interceptors.push(function ($location) { return { 'responseError': function () { //will do more later console.log('Response Error'); $location.path('/error'); } } }) }]);
Step-15: Add an another javascript file in the ngServices folder and write below code.
Go to solution explorer > Right click on ngServices folder (inside Scripts > ngComponents) > Add > New Item > Select javascript file under Scripts > enter file name > Click on Add button.
var app = angular.module('myContactBook'); app.factory('contactService', ['$http', '$q', function ($http, $q) { var fac = {}; fac.GetContacts = function () { var defer = $q.defer(); $http.get('/home/getcontacts') .success(function (data) { defer.resolve(data); }); return defer.promise; } fac.GetContact = function (contactID) { var defer = $q.defer(); $http.get('/home/getcontact', { params: { 'contactID' : contactID } }) .success(function (data) { defer.resolve(data); }); return defer.promise; } fac.SaveContact = function (contact) { var defer = $q.defer(); $http({ method: "post", url: '/home/savecontact', data : contact }).then(function (response) { defer.resolve(response.data); }) return defer.promise; } fac.DeleteContact = function (contactID) { var defer = $q.defer(); $http({ method: 'POST', url: '/home/DeleteContact', data : {'contactID' : contactID} }).then(function (response) { defer.resolve(response.data); }) return defer.promise; } return fac; }]);
Step-16: Add 3 more javascript file in the ngControllers folder for add 3 angular controller.
- homeController.js
- saveContactController.js
- errorController.js
homeController.js
var app = angular.module('myContactBook'); app.controller('homeController', ['$scope', 'contactService', function ($scope, contactService) { $scope.contacts = []; function populateContacts() { contactService.GetContacts().then(function (data) { $scope.contacts = data; }) } populateContacts(); $scope.DeleteContact = function (contactID) { if (confirm('Are you sure?')) { //Delete contact here contactService.DeleteContact(contactID).then(function (data) { if (data.status) { populateContacts(); } }); } } }]);
saveContactController.js
var app = angular.module('myContactBook'); app.controller('saveContactController', ['$scope', '$routeParams', '$location', 'contactService' , function ($scope, $routeParams, $location, contactService) { $scope.IsFormSubmitted = false; $scope.IsFormValid = false; $scope.Contact = {}; //Populate data for edit mode if ($routeParams.id > 0) { //Edit mode contactService.GetContact($routeParams.id).then(function (data) { $scope.Contact = data; }) } else { //Add new $scope.Contact.ContactID = 0; } // check form $scope.$watch('contactForm.$valid', function (newValue) { $scope.IsFormValid = newValue; }); //submit form $scope.Submit = function () { debugger; $scope.IsFormSubmitted = true; if ($scope.IsFormValid) { contactService.SaveContact($scope.Contact).then(function (data) { if (data.status) { alert('Contact saved successfully.'); $location.path('/home'); } else { alert('Error! Please try again.'); console.log(data.message); } }) } } }])
errorController.js
var app = angular.module('myContactBook'); app.controller('errorController', ['$scope', function ($scope) { $scope.ErrorMessage = "Error! Please try again."; }])
Step-17: Add 3 HTML files in the ngTemplates folder for add 3 angular templates.
- home.html
- savecontact.html
- error.html
<h2>Contact List</h2> <hr/> <table class="table table-responsive"> <tr> <th>Contact Name</th> <th>Contact No</th> <th>Email</th> <th>Address</th> <th></th> <th></th> </tr> <tr ng-repeat="contact in contacts"> <td ng-bind="contact.ContactName"></td> <td ng-bind="contact.ContactNo"></td> <td ng-bind="contact.EmailID"></td> <td ng-bind="contact.Address"></td> <td><a href="#/savecontact/{{contact.ContactID}}">Edit</a></td> <td><a target="_self" ng-click="DeleteContact(contact.ContactID)">Delete</a></td> </tr> </table>
savecontact.html
<h2>Save contact</h2> <hr /> <form novalidate role="form" name="contactForm" ng-submit="Submit()"> <div class="form-group"> <label for="ContactName">Contact Name: </label> <input type="text" name="ContactName" ng-model="Contact.ContactName" ng-class="IsFormSubmitted ? 'ng-dirty' : ''" class="form-control" required /> <span class="error" ng-show="(contactForm.ContactName.$dirty || IsFormSubmitted) && contactForm.ContactName.$error.required">Contact Name required.</span> </div> <div class="form-group"> <label for="ContactNo">Contact No: </label> <input type="text" name="ContactNo" ng-model="Contact.ContactNo" ng-class="IsFormSubmitted ? 'ng-dirty' : ''" class="form-control" required /> <span class="error" ng-show="(contactForm.ContactNo.$dirty || IsFormSubmitted) && contactForm.ContactNo.$error.required">Contact No required.</span> </div> <div class="form-group"> <label for="EmailID">Email ID: </label> <input type="email" name="EmailID" ng-model="Contact.EmailID" ng-class="IsFormSubmitted ? 'ng-dirty' : ''" class="form-control" /> <span class="error" ng-show="(contactForm.EmailID.$dirty || IsFormSubmitted) && contactForm.EmailID.$error.email">Invalid email.</span> </div> <div class="form-group"> <label for="Address">Address: </label> <textarea name="Address" ng-model="Contact.Address" class="form-control"></textarea> </div> <input type="submit" class="btn btn-default" /> </form>
error.html
<h2>Error</h2> <hr/> <p> {{ErrorMessage}} </p>
Step-18: modify _Layout.cshtml page for bootstrap angular application.
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - My ASP.NET Application</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head> <body ng-app="myContactBook" > <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> @Html.ActionLink("Application name", "Index", "Home", null, new { @class = "navbar-brand" }) </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="#/home">Home</a></li> <li><a href="#/savecontact/0">Add Contact</a></li> </ul> </div> </div> </div> <div class="container body-content"> @RenderBody() <ng-view></ng-view> <hr /> <footer> <p>© @DateTime.Now.Year - My ASP.NET Application</p> </footer> </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) <script src="~/Scripts/angular.js"></script> <script src="~/Scripts/angular-route.js"></script> <script src="~/Scripts/ngComponents/ngConfigs/main.js"></script> <script src="~/Scripts/ngComponents/ngControllers/homeController.js"></script> <script src="~/Scripts/ngComponents/ngControllers/saveContactController.js"></script> <script src="~/Scripts/ngComponents/ngControllers/errorController.js"></script> <script src="~/Scripts/ngComponents/ngServices/contactService.js"></script> <style> .error { color: red; } </style> </body> </html>