A simple SPA with AngularJs, ASP.NET MVC, Web API and EF

SPA stands for Single Page Application. Here I will demonstrate a simple SPA with ASP.NET MVC, Web API and Entity Framework. I will show a trainer profile and its CRUD operation using AngularJS, ASP.NET MVC, Web api and Entity Framework.

Step 1: Create a ASP.NET MVC application with empty template

Open visual studio, Got to File->New->Project
Select Template -> Visual C# -> Web -> ASP.NET MVC 4 Web application and click OK
Select Empty Template and Razor as view engine

Step 2: Install required packages
Run the following command in Package Manager Console (Tools->Library Package Manager->Package Manager Console) to install required package. Make sure your internet connection is enabled.

PM> Install-Package jQuery
PM> Install-Package angularjs -Version 1.2.26
PM> Install-Package Newtonsoft.Json
PM> Install-Package MvcScaffolding

Step 3: Create Connection String
Create connection string and name DB name as SPADB

  
    
  

Step 4: Create model

Create Trainer model

    public class Trainer
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Venue { get; set; }
    }

Step 5: Create Repository
Create repository for Trainer model. Run the following command in Package Manager Console (Tools->Library Package Manager->Package Manager Console) to create repository. I used repository pattern for well-structured and more manageable.

PM> Scaffold Repository Trainer

After running the above command you will see SPAContext.cs and TrainerRepository.cs created in Model folder. For well manageability, I create a directory name Repository and put these two files in the Repository folder. So change the namespace as like SPA.Repository instead of SPA.Model. I also create a UnitOfWork for implement unit of work pattern.

The overall folder structure looks like following.

st-final

SPAContext.cs

    public class SPAContext : DbContext
    {
        public SPAContext()
            : base("SPAContext")
        {
        }
        // You can add custom code to this file. Changes will not be overwritten.
        // 
        // If you want Entity Framework to drop and regenerate your database
        // automatically whenever you change your model schema, add the following
        // code to the Application_Start method in your Global.asax file.
        // Note: this will destroy and re-create your database with every model change.
        // 
        // System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges());

        public DbSet Trainers { get; set; }

        public DbSet Trainings { get; set; }
    }

TrainerRepository.cs

    public class TrainerRepository : ITrainerRepository
    {
        SPAContext context = new SPAContext();

        public TrainerRepository()
            : this(new SPAContext())
        {

        }
        public TrainerRepository(SPAContext context)
        {
            this.context = context;
        }


        public IQueryable All
        {
            get { return context.Trainers; }
        }

        public IQueryable AllIncluding(params Expression>[] includeProperties)
        {
            IQueryable query = context.Trainers;
            foreach (var includeProperty in includeProperties)
            {
                query = query.Include(includeProperty);
            }
            return query;
        }

        public Trainer Find(long id)
        {
            return context.Trainers.Find(id);
        }

        public void InsertOrUpdate(Trainer trainer)
        {
            if (trainer.Id == default(long))
            {
                // New entity
                context.Trainers.Add(trainer);
            }
            else
            {
                // Existing entity
                context.Entry(trainer).State = System.Data.Entity.EntityState.Modified;
            }
        }

        public void Delete(long id)
        {
            var trainer = context.Trainers.Find(id);
            context.Trainers.Remove(trainer);
        }

        public void Save()
        {
            context.SaveChanges();
        }

        public void Dispose()
        {
            context.Dispose();
        }
    }

    public interface ITrainerRepository : IDisposable
    {
        IQueryable All { get; }
        IQueryable AllIncluding(params Expression>[] includeProperties);
        Trainer Find(long id);
        void InsertOrUpdate(Trainer trainer);
        void Delete(long id);
        void Save();
    }

UnitOfWork.cs

    public class UnitOfWork : IDisposable
    {
        private SPAContext context;
        public UnitOfWork()
        {
            context = new SPAContext();
        }

        public UnitOfWork(SPAContext _context)
        {
            this.context = _context;
        }

        private TrainingRepository _trainingRepository;

        public TrainingRepository TrainingRepository
        {
            get
            {

                if (this._trainingRepository == null)
                {
                    this._trainingRepository = new TrainingRepository(context);
                }
                return _trainingRepository;
            }
        }


        private TrainerRepository _trainerRepository;

        public TrainerRepository TrainerRepository
        {
            get
            {

                if (this._trainerRepository == null)
                {
                    this._trainerRepository = new TrainerRepository(context);
                }
                return _trainerRepository;
            }
        }

        public void Dispose()
        {
            context.Dispose();
            GC.SuppressFinalize(this);
        }
    }

Step 6: Add migration

Run the following command to add migration
PM> Enable-Migrations
PM> Add-Migration initialmigration
PM> Update-Database –Verbose

Step 7: Create API Controllers
Create Trainers api Controllers by clicking right button on Controller folder and scaffold as follows.

TrainersController-2

Step 8: Modify Controllers

Now modify the controllers as follows. Here I used unit of work pattern.

    public class TrainersController : ApiController
    {
        private UnitOfWork unitOfWork = new UnitOfWork();

        public IEnumerable Get()
        {
            List lstTrainer = new List();
            lstTrainer = unitOfWork.TrainerRepository.All.ToList();
            return lstTrainer;
        }

        //// GET api/trainers/5
        public Trainer Get(int id)
        {
            Trainer objTrainer = unitOfWork.TrainerRepository.Find(id);
            return objTrainer;
        }

   
        public HttpResponseMessage Post(Trainer trainer)
        {

            if (ModelState.IsValid)
            {
                unitOfWork.TrainerRepository.InsertOrUpdate(trainer);
                unitOfWork.TrainerRepository.Save();
                return new HttpResponseMessage(HttpStatusCode.OK);
            }
            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }


        private IEnumerable GetErrorMessages()
        {
            return ModelState.Values.SelectMany(x => x.Errors.Select(e => e.ErrorMessage));
        }

   

        // PUT api/trainers/5
        public HttpResponseMessage Put(int Id, Trainer trainer)
        {
            if (ModelState.IsValid)
            {
                unitOfWork.TrainerRepository.InsertOrUpdate(trainer);
                unitOfWork.TrainerRepository.Save();
                return new HttpResponseMessage(HttpStatusCode.OK);
            }
            else
                return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }

        // DELETE api/trainers/5
        public HttpResponseMessage Delete(int id)
        {
            Trainer objTrainer = unitOfWork.TrainerRepository.Find(id);
            if (objTrainer == null)
            {
                return new HttpResponseMessage(HttpStatusCode.InternalServerError);
            }

            unitOfWork.TrainerRepository.Delete(id);
            unitOfWork.TrainerRepository.Save();

            return new HttpResponseMessage(HttpStatusCode.OK);
        }
    }

Step 9: Create Layout and Home Controller
Create _Layout.cshtml in Views->Shared folder and create HomeController and create inext view of Home controller by right click on index action and add view. You will see index.cshtml is created in Views->Home

Home Controller

    public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            return View();
        }

    }

_Layout.cshtml



    Training Registration



    @RenderBody()



Index.cshtml


@{
    ViewBag.Title = "Home";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

Home

Step 10: Create registrationModule

Create registrationModule.js in Scripts->Application. This is for angularjs routing.


var registrationModule = angular.module("registrationModule", ['ngRoute', 'ngResource'])
    .config(function ($routeProvider, $locationProvider) {

        $routeProvider.when('/Registration/Trainers', {
            templateUrl: '/templates/trainers/all.html',
            controller: 'listTrainersController'
        });

        $routeProvider.when('/Registration/Trainers/:id', {
            templateUrl: '/templates/trainers/edit.html',
            controller: 'editTrainersController'
        });

        $routeProvider.when('/Registration/Trainers/add', {
            templateUrl: '/templates/trainers/add.html',
            controller: 'addTrainersController'
        });

        $routeProvider.when("/Registration/Trainers/delete/:id", {
            controller: "deleteTrainersController",
            templateUrl: "/templates/trainers/delete.html"
        });

        $locationProvider.html5Mode(true);
    });

Step 11: Create trainerRepository

Create trainerRepository.js in Scripts->Application->Repository. This increase manageability for large application.


'use strict';

//Repository for trainer information
registrationModule.factory('trainerRepository', function ($resource) {

    return {
        get: function () {
            return $resource('/api/Trainers').query();
        },

        getById: function (id) {
            return $resource('/api/Trainers/:Id', { Id: id }).get();
        },

        save: function (trainer) {
            return $resource('/api/Trainers').save(trainer);
        },

        put: function (trainer) {
            return $resource('/api/Trainers', { Id: trainer.id },
                {
                    update: { method: 'PUT' }
                }).update(trainer);
        },

        remove: function (id) {
            return $resource('/api/Trainers').remove({ Id: id });
        }
    };

});

Step 12: Create trainerController

Create trainerController.js in Scripts->Application->Controllers

'use strict';

//Controller to get list of trainers informaion
registrationModule.controller("listTrainersController", function ($scope, trainerRepository, $location) {
    $scope.trainers = trainerRepository.get();
});


//Controller to save trainer information
registrationModule.controller("addTrainersController", function ($scope, trainerRepository, $location) {
    $scope.save = function (trainer) {
        trainer.Id = 0;
        $scope.errors = [];
        trainerRepository.save(trainer).$promise.then(
            function () { $location.url('Registration/Trainers'); },
            function (response) { $scope.errors = response.data; });
    };
});


//Controller to modify trainer information
registrationModule.controller("editTrainersController", function ($scope,$routeParams, trainerRepository, $location) {
    $scope.trainer = trainerRepository.getById($routeParams.id);

    $scope.update = function (trainer) {
        $scope.errors = [];
        trainerRepository.put(trainer).$promise.then(
            function () { $location.url('Registration/Trainers'); },
            function (response) { $scope.errors = response.data; });
    };
});

//Controller to delete trainer information
registrationModule.controller("deleteTrainersController", function ($scope, $routeParams, trainerRepository, $location) {
        trainerRepository.remove($routeParams.id).$promise.then(
            function () { $location.url('Registration/Trainers'); },
            function (response) { $scope.errors = response.data; });
});

Step 13: Create templates
Create all.html, add.html, edit.html, delete.html in templateds->trainers folder.

All.html

Trainers Details

Name Email Venue Action
{{trainer.name}} {{trainer.email}} {{trainer.venue}} Delete |Edit

Add.html


Trainer Name
Email
Venue
Cancel

Edit.html

Name
Email
Venue

Step 14: Add references to the Layout
Modify the _Layout.cshtml to add references

_Layout.cshtml






    Training Registration

    
    
    
    
    
    
    



    @RenderBody()



Now run you application and add, delete, modify and get all trainer information. Thanks for your patient!

Install and uninstall windows service from command prompt

Suppose you have created a windows service name “YourServiceName.exe”. Now you want to install or uninstall it from command prompt.

  • To Install Service run the commnad:

C:\Windown\Microsoft.Net\framework\v2.0\installUtil.exe  C:\dirctory\YourServeceName.exe     (with location)

  • To Uninstall Service run the command:

C:\Windown\Microsoft.Net\v2.0\installUtil.exe /u C:\dirctory\YourServeceName.exe         (with location)

Introduction to Web services with ASP.NET

What is Web Services?

Web service is a method of communication between two web based application using XML, SOAP, WSDL and UDDI open standards over an internet protocol backbone. Web service can convert your application into web application which can publish its function or message to the rest of the world). Web service are-

  • Web services are application components
  • Web services communicate with open protocols
  • Web services are self-contained and self-describing
  • Web services can be discovered using UDDI (*4)
  • Web services can be used by other applications
  • XML is the basis of web services

Why Web Services?

Different web applications in the web want to interact with each other. Such as application can share data, can invoke method of other application. So, how can you solve this? It will also be a great problem if applications are in different platform and language. Web service solves the above issues.

By using Web services, your application can publish its function or message to the rest of the world. Web services use XML to code and to decode data, and SOAP to transport it (using open protocols). With Web services, your accounting department’s Win 2k server’s billing system can connect with your IT supplier’s UNIX server

Web services have two types of uses:

Reusable Application Component – currency conversion, weather reports, language translation.Connect Existing Software – Web services can help to solve the interoperability problem by giving different applications a way to link their data.

How does it work?

The basic web service platform is XML + HTTP. Web service elements are –

  • SOAP – Simple Object Access Protocol
  • UDDI – Universal Description, Discovery and Integration
  • WSDL – Web Service Description Language

With ASP.net, you do not have to write SOAP and WSDL documents. ASP.net automatically creates SOAP and WSDL documents.

Example:

Simple Addition Method: Here I have tried to represent web service before you by a simple add method which takes two parameter as two integer value and it returns the addition of these two.

Step 1: Create Asp.net Web service

1.Create an Asp.net website.

of-1

of-2

  1. Click right button on asp.net web site.
  2. Click on add new Item.
  3. Select Web service like the below screen.

of-3

  1. Right click on WebService.asmx and select view code. You will see the following code snippet. It should be mentioned here that I have created my web service named WebService which you have already seen in previous screen.
using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Services;

///

/// Summary description for WebService

///

[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.

// [System.Web.Script.Services.ScriptService]

public class WebService : System.Web.Services.WebService {

public WebService () {

//Uncomment the following line if using designed components

//InitializeComponent();

}

[WebMethod]

public string HelloWorld()

{

return "Hello World";

}

}
  1. Simply add a Method name Add as like below.
/// Copyright : Copyright© mahedee.hasan@gmail.com. All rightsreserved.

/// NameSpace :

/// Class : WebService

/// Inherits : System.Web.Services.WebService

/// Author : Md. Mahedee Hasan

/// Purpose : This is a simple web service to add two number

/// Creation Date : 21/01/2012

/// =========================================================================================

/// || Modification History ||

/// ------------------------------------------------------------------------------------

/// Sl No. Date: Author: Ver: Area of Change:

/// 1. 21/01/2012 Mahedee 1.0 Created

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Services;

///

/// Summary description for WebService

///

[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.

// [System.Web.Script.Services.ScriptService]

public class WebService : System.Web.Services.WebService {

public WebService () {

//Uncomment the following line if using designed components

//InitializeComponent();

}

[WebMethod]

public string HelloWorld()

{

return "Hello World";

}

[WebMethod]

public int Add(int firstVal, int secondVal)

{

return firstVal + secondVal;

}

}
  1. .Click right button on WebService.asmx and select Set As Start Page
  2. Run Project or press F5. You will see the following screen.

of-4

9. Click Add method, you will see the following screen.

of-5
10. Suppose I input two value 12 and 30. Click Invoke.

of-6
.11. After clicking Invoke you will get the addition of two values as XML format.

Now your web service is ready to use. We have to use web service in various ways. In the next step I will show how to access web service from client page.

Step 2: Create a client page and access web service.

There are many ways to consume web service. Here is an example of HTML-POST protocol which is one of the ways of consuming web service.

1. Create a aspx/html page. I have used here an aspx page name “ClientForm.aspx”.
2. Add the following tags in aspx source.
3. In action attribute of form tag, I have used localhost because I have already hosted it. You can simply use “http://localhost:5143/Web/WebService.asmx/Add” in  action attribute instead of present value in action attribute if you didn’t host website in your local machine. Here 5143 can vary.


input> input> input> div> form>

4. Click right button on ClientForm.aspx and select Set As Start Up page.
5. Run your project.
6. You will see the following screen.

of-7
7. Enter two values of two textbox.
8. Press Enter you will get the result in xml format.

25int> 

This is the basic example and web service. You will see more about web service next.

Notes:

  1. XML provides a language which can be used between different platforms and programming languages and still express complex messages and functions.
  2. SOAP: The HTTP protocol is the most used Internet protocol.

SOAP is an XML-based protocol to let applications exchange information over HTTP.

Or more simple: SOAP is a protocol for accessing a Web Service.

  • SOAP stands for Simple Object Access Protocol
  • SOAP is a communication protocol
  • SOAP is a format for sending messages
  • SOAP is designed to communicate via Internet
  • SOAP is platform independent
  • SOAP is language independent
  • SOAP is based on XML
  • SOAP is simple and extensible
  • SOAP allows you to get around firewalls
  • SOAP is a W3C standard
  1. WSDL:

WSDL is an XML-based language for locating and describing Web services.

  • WSDL stands for Web Services Description Language
  • WSDL is based on XML
  • WSDL is used to describe Web services
  • WSDL is used to locate Web services
  • WSDL is a W3C standard
  1. UDDI:

UDDI is a directory service where companies can register and search for Web services.

  • UDDI stands for Universal Description, Discovery and Integration
  • UDDI is a directory for storing information about web services
  • UDDI is a directory of web service interfaces described by WSDL
  • UDDI communicates via SOAP
  • UDDI is built into the Microsoft .NET platform