Click here to Skip to main content
15,119,514 members
Articles / Web Development / HTML
Posted 20 Mar 2012


154 bookmarked

A simple POC using ASP.NET Web API, Entity Framework, Autofac, Cross Domain Support

Rate me:
Please Sign up or sign in to vote.
4.92/5 (43 votes)
27 Oct 2012CPOL11 min read
The purpose of this article is to create a proof of concept to demonstrate the feasibility of ASP.NET Web API Beta Version.





Download CodePlex  


The purpose of this article is to create a proof of concept to demonstrate the feasibility of ASP.NET WebAPI final release.


  • Modify code for Visual Studio 2012
  • Replace Autofac with Castle Windsor for Dependency Injection   


Goals to achieve: 

  • Any user should be able to view products
  • Product would be filtered by Categories
  • User should be able to add products in cart
  • Only registered user will be able to submit cart
  • User should be able to register into system
  • User will get confirmation Invoice after generating order in system.

Architecture for this POC

I am not following any specific Architecture Pattern, although while designing this POC, I try to follow some of the key design principles like:

Again I am repeating my word try to follow….. :). So, all comments/suggestions are more than welcome to discuss and I am always ready to adopt changes, or you can do it yourself by join @CodePlex. The initial Skeleton for this application is as per below diagram:



Step 1: Create a basic Application Structure Layout

For more information on ASP.NET WebAPI, watch Videos and Tutorials here

Add a blank Solution named as Application

Add a new Project (Class Library) named as Application.DAL

Repeat above process and create four more Class Library projects named as –

  • Application.Model
  • Application.Repository
  • Application.Common
  • Application.Service
Now, application will look like below screen-shot

Solution 1

Next, add a new Project named as Application.API as ASP.Net MVC 4 Web Application. After click on OK, select template as Web API

This will add a full functional Web API template Application into our main solution.

Solution 1

Right click on Application.API project in Solution Explorer and go to properties, than assign a port to be use by this service application ( In my case its 30000). Hit F5 and we are ready with a dummy data as below screen:

Solution 1

Step 2: Prepare Application.DAL, Application.Repository and Application.Model Layers

Check @MSDN for more information on Entity Framework

Add Entity Data Model to Application.DAL project. To do this select ADO.NET Entity Data Model from the Data Templates list, and name it as AdventureWorks.edmx

Choose “Generate from Database” and provide the connection string to read the database schema. This will add AdventureWorks.edmx into current project. Right click on the blank space in Entity Model surface and click on properties (or alternate press Alt +Enter on keyboard). Now set its Code Generation Strategy as None.

Solution 1

Now create POCO entities for AdventureWorks Data Model into Application.Model Solution. Check this article to do this job for you on MSDN to use T4 Templates and the Entity Framework
Then, create all required repositories under Application.Repositories.

Solution 1

To build solution, add reference of Application.Model.dll to Application.DAL.dll and Application.Repository.dll projects, and add reference of Application.DAL.dll to Application.Repository.dll project. (See below picture for reference)
Before proceeding to next step (designing Application.Service and Application.API Layer), let us see what we have designed yet:

Solution 1

Step 3: Add files to Application.Service Layer

Before adding files to Service layer let us look at the Goals which we want to achieve.

  • Any user should be able to view products
  • Product would be filtered by Categories
  • User should be able to add products in cart
  • Only registered user will be able to submit cart
  • User should be able to register into system
  • User will get confirmation Invoice after generating order in system.

To achieve the above mention Goals, we need to add three service classes to Application.Service as per below image

Solution 1

Solution 1

I am not going in deatils, as the implementation for each methods are clear and easy to understand.

Step 4: Add files to Application.API Layer

To make this Web API accessed from a broad range of clients like any browsers which use JavaScript or any windows/Mobile platform which supports .dll files, we need to add Controllers with base class as ApiController. More details here

First, we remove the default controllers added by template (HomeController and ValuesController) and then add three new controllers as per below diagram:

Solution 1

Again, nothing special in the implementation of these methods, they all jst push the data to service layer.

Step 5: Integration of Dependency Injection with WebAPI using Castle Windsor 

The implementation is very much straight forward and clear.  

In Application.API Solution Explorer, right-click the References node and click Manage NuGet Packages

Solution 1

It will open the below screen. 

Image 12 

 Click on install and it will add below two references in solution

Image 13 

Create an adopter for Castle Windsor as WindsorActivator to implement IHttpControllerActivator  

public class WindsorActivator : IHttpControllerActivator
    private readonly IWindsorContainer container;

    public WindsorActivator(IWindsorContainer container)
        this.container = container;

    public IHttpController Create(
        HttpRequestMessage request,
        HttpControllerDescriptor controllerDescriptor,
        Type controllerType)
        var controller =

            new Release(
                () => this.container.Release(controller)));

        return controller;

    private class Release : IDisposable
        private readonly Action release;

        public Release(Action release)
            this.release = release;

        public void Dispose()


 The installer uses the container parameter of the Install method to Register controllers using Windsor's Fluent Registration API. 

Now we need to tell Castle Windsor to know about all dependencies for it to manage them. For that, we create a new class DependencyInstaller to implement IWindsorInstaller. The installer uses the container parameter of the Install() method to Register dependencies using Windsor's Fluent Registration API. As per below implementation every time we add any new class to Controller/Service/Repository in our application, it will be automatically registered, the only thing we need follow is naming convention, i.e. all Controller class should end with Controller similarly Service and Repository classes should end with Service and Repository. 

    public void Install(IWindsorContainer container, IConfigurationStore store)




                        .Where(type => type.Name.EndsWith("Service")).WithServiceAllInterfaces().LifestylePerWebRequest(),

                        .Where(type => type.Name.EndsWith("Repository")).WithServiceAllInterfaces().LifestylePerWebRequest()

 Next, in final step create and configure the Windsor container in Application's constructor inside Global.asax.cs,  so that it will be automatically dispose when application exits. 

public class WebApiApplication : System.Web.HttpApplication
    private readonly IWindsorContainer container;

    public WebApiApplication()
        this.container =
            new WindsorContainer().Install(new DependencyInstaller());

    public override void Dispose()

    protected void Application_Start()

            new WindsorActivator(this.container));

Now we are ready to test our application. Hit F5 and check the browser with following url’s:
http://localhost:30000/api/products : will result all Product Categories

Solution 1

http://localhost:30000/api/products/2 : will result all Products with ProductcategoryID as 2

Solution 1

To check other methods, First we will add some Views in current solution.

Step 6: Add View to solution

Delete all default files and folders from Views Folder, and add three Html and their supportive Javascript File as. For this POC we will use html files, and some jquery libraries like:

jquery.tmpl.js : to create template based screen, and

jquery.validationEngine.js : to validate form data

Now the structure will looks like below picture :

Solution 1

For details code in html and JS file please look into the code. In next step I am going to resolve problems.

Step 7: Resolve issues

Before run the application Right Click on Products.htm and click on Set As start Page. Now hit F5

Solution 1

It means, two WebAPI methods in ProductsController.cs are working perfectly. In JavaScript, on page load we are calling first method inside product.js as:

var productcategoriesAddress = "/api/products/";
$(function () {
            function (data) {
                var parents = jQuery.grep(data, function (a) { return a.ParentProductCategoryID == null });
                var childs = jQuery.grep(data, function (a) { return a.ParentProductCategoryID != null });
                    function (index, value) {
                        var categorydata = [];
                        var subCategory = '';
                        var subChild = jQuery.grep(childs, function (a) { return a.ParentProductCategoryID == value.ProductCategoryID });
                            function (index, item) {
                                var serviceURL = productcategoriesAddress + item.ProductCategoryID;
                                subCategory = subCategory + "  " + "<a href="%20+%20serviceURL%20+%20" class="menuButton">" + item.Name + "</a>";
                            'ProductCategoryID': value.ProductCategoryID,
                            'ParentCategory': value.Name,
                            'ChildCategory': subCategory
                        $("#" + value.Name).html(subCategory);


This call hits below method in ProductsController, and returns all Product Category to create the Upper Menu Part

    public IQueryable<productcategory> GetProductCategories()
        loggerService.Logger().Info("Calling with null parameter");
        return _productservice.GetProductCategories().AsQueryable<productcategory>();

In ProductService implementation is :

    public IQueryable<productcategory> GetProductCategories()
        loggerService.Logger().Info("Calling with null parameter");
        return _productservice.GetProductCategories().AsQueryable<productcategory>();

The second call is to fetch all products depends on selected category. In javascript

  function GetProducts(ProductCategoryID) {
    var serviceURL = productcategoriesAddress + ProductCategoryID;
    $('#categories li h1').css('background', '#736F6E');
    $('#mnu' + ProductCategoryID).css('background', '#357EC7');
        type: "GET",
        datatype: "json",
        url: serviceURL,
        context: this,
        success: function (value) {
    return false;

and in ProductsController it goes to

    public IQueryable<product> GetProductByProductCategoryID(int id)
        loggerService.Logger().Info("Calling with null parameter as : id : " + id);
        return _productservice.GetProductByProductCategoryID(id).AsQueryable<product>();


In ProductService implementation is :

    public IQueryable<product> GetProductByProductCategoryID(int id)
        loggerService.Logger().Info("Calling with null parameter as : id : " + id);
        return _productservice.GetProductByProductCategoryID(id).AsQueryable<product>();

Next, let us try to add some products to Cart and Checkout cart

Solution 1

On clicking on checkout It redirect to Checkout.htm page and asking for either Login using existing CustomerID or Register for a new Customer.
Click on Register link to create a new Customer.

Solution 1

Submit form after clicking on Register button and see if Posting is working or not. Again its success!!!

Now we will try to update records for AddressLine2, and Update is also working fine!!!

In both scenario (Add or Update Customer) we are calling below method of CutomerControllers.cs

 public int PostCustomer(CustomerDTO customer)
    loggerService.Logger().Info("Calling with parameter as : customer: " + customer);
    return _customerService.SaveOrUpdateCustomer(customer);

In CustomerService implementation is :

public int SaveOrUpdateCustomer(CustomerDTO customer)
    string passwordSalt = CreateSalt(5);
    string pasword = CreatePasswordHash(customer.Password, passwordSalt);
    Customer objCustomer;

    if (customer.CustomerID != 0)
        objCustomer = _customerRepository.GetById(customer.CustomerID);
        objCustomer = new Customer();

    objCustomer.NameStyle = customer.NameStyle;
    objCustomer.Title = customer.Title;
    objCustomer.FirstName = customer.FirstName;
    objCustomer.MiddleName = customer.MiddleName;
    objCustomer.LastName = customer.LastName;
    objCustomer.Suffix = customer.Suffix;
    objCustomer.CompanyName = customer.CompanyName;
    objCustomer.SalesPerson = customer.SalesPerson;
    objCustomer.EmailAddress = customer.EmailAddress;
    objCustomer.Phone = customer.Phone;
    objCustomer.PasswordHash = pasword;
    objCustomer.PasswordSalt = passwordSalt;
    objCustomer.ModifiedDate = DateTime.Now;
    objCustomer.rowguid = Guid.NewGuid();

    if (customer.CustomerID != 0)

    SaveOrUpdateAddress(customer, objCustomer.CustomerID);
    return objCustomer.CustomerID;

Next, click on Submit Order Button, to make previously selected products as an Order and receive Order Invoice.

Solution 1

!!!Hurray!!! Order is created in system and invoice is generated with a new Purchase Order. But, wait we got one BUG 

Issue 1. is fixed with the final release of Asp.Net WebAPI  

Issue 1: we have an issue with Date Format.

Solution 1

According to, Scott Hanselman’s post this is a bug and will resolve in next release of ASP.Net WebAPI. This issue is resolved using solution provided in Henrik's Blog.

Solution 1

Issue 2: Another issue was, when I try to Checkout Cart using the last created Customer. The error was:

Solution 1

After looking this error, first thought comes that we missed the method in CustomersController.cs, but the method was already there. Further investigation make it clear, that, the reason behind this error was name of this method as ValidateCustomer():

 public CustomerDTO ValidateCustomer(int id, string password)
    loggerService.Logger().Info("Calling with parameter as : id and password: " + id + " and " + password);
    return _customerService.ValidateCustomer(id, password);

In CustomerService implementation is :

public CustomerDTO ValidateCustomer(int id, string password)
    Customer objCustomer = _customerRepository.GetById(id);
    if (objCustomer == null)
        return null;
    string strPasswordHash = objCustomer.PasswordHash;
    string strPasswordSalt = strPasswordHash.Substring(strPasswordHash.Length - 8);
    string strPasword = CreatePasswordHash(password, strPasswordSalt);

    if (strPasword.Equals(strPasswordHash))
        return CreateCustomerDTO(objCustomer);
        return null;

By default the route configuration of Asp.Net WebAPI follows RESTFUL conventions meaning that it will accept only the Get, Post, Put and Delete action names. So when we send a GET request to http://localhost:30000/api/customers/ValidateCustomer/30135/test we are basically calling the Get(int id) action and passing id=30135 which obviously crashes because we don’t have any method starting with Get which accept Id as parameter. To resolve this issue I need to add a new route definition in Global.asax file as:

      name: "ValidateCustomer",
      routeTemplate: "api/{controller}/{action}/{id}/{password}",
      defaults: new { action = "get" }

Adding this line done the magic and Login functinality start waorking…. :)

Step 8: Deploy on IIS

To deploy this API on IIS version 7.5, first, publish only Application.API solution to a Folder.

Next, open IIS Manager and create a new website and set path to Publish folder, and we are done with deployment.

Now, check whether page is opening or not, in my case, initially I got below error, which is self-explanatory.
The error comes because this application is running on Asp.Net Framework Version 2.0. So, we need to change it to Asp.Net Framework Version 4.0:

Solution 1

Solution 1

To change the Asp.Net Framework from 2.0 to 4.0, follow below steps.

Solution 1

Solution 1

That was not the only reason not to run application, because after made above change in Application pool next error was:

Solution 1

To resolve this error again go to Advance Settings of Application pool and change the identity to Local System from ApplicationPoolIdentity

Solution 1

After modify the Application pool to use Local System, Application starts working on browser... :)

Solution 1

Note:Although IIS errors are depending on servers/Firewall/Network or system to system, so it is very difficult to assume that you will also get the same error as mine. Check these links which help me to resolve some of the IIS issues in my work environment.

Step 9: Cross Domain Support

The idea behind the Cross Domain Support comes when I try to remove all HTML pages from Application.API solution and created a new Empty Web Application (Adventure.Website) which includes only .html, .Js and .css files along with images. The structure for this application is as per below image:

Solution 1

Point all URL address to deployed code on IIS, after build and run application, output was null.

Solution 1

To resolve this issue I would like to give my special thanks to Carlos’ blog on MSDN Implementing CORS support in ASP.NET Web APIs

“By default, a web page cannot make calls to services (APIs) on a domain other than the one where the page came from. This is a security measure against a group of cross-site forgery attacks in which browsing to a bad site could potentially use the browser cookies to get data from a good site which the user had previously logged on (think your bank). There are many situations, however, where getting data from different sites is a perfectly valid scenario, such as mash-up applications which need data from different sources.”  

Code Setup 

Due to size restriction I have attached code in three parts :

 Part 1 : Application.Zip 

 Part 2 : Packages.Zip 

 Part 3 : AdventureSite.Zip 

Part 1 and Part 3 are independent applications. Whereas, for Part 2 we need to copy its content inside the package folder of Application (Part 1). Please refer below image :

 Image 33 


That's it !!! Hope you enjoy this article. I am not an expert, and also I have not followed the entire industry standard at the time of writing this article (time factor).

All comment/Vote are more than welcome…. :), whenever, I get time, will try to modify this solution. You can also join/contribute to this project on CodePlex.

Thank's for your time.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Anand Ranjan Pandey
Software Developer (Senior)
United States United States
No Biography provided

Comments and Discussions

QuestionHow to set lazy loading in some models Pin
Member 1412982713-Apr-19 2:30
MemberMember 1412982713-Apr-19 2:30 
BugGetting exception in WendsorActivator.cs in Create Method Pin
sandeep cogni20-Jan-16 6:30
Membersandeep cogni20-Jan-16 6:30 
QuestionHow to user with normal Control? Pin
Sunasara Imdadhusen15-May-15 2:34
professionalSunasara Imdadhusen15-May-15 2:34 
AnswerPerfect Solution to Start with Pin
pateldeepp30-Dec-14 1:07
Memberpateldeepp30-Dec-14 1:07 
QuestionHow to access DTO objects in Application.Web project present in Application.Model to create new controllers? Pin
maruthipuligandla16-Jul-14 23:58
Membermaruthipuligandla16-Jul-14 23:58 
QuestionHow can I create one repository instead of making repositories for each table Pin
aliasgar raj25-Jun-14 21:36
Memberaliasgar raj25-Jun-14 21:36 
QuestionThank you. Pin
Member 1003833923-Apr-14 18:47
professionalMember 1003833923-Apr-14 18:47 
Generalcan you add your template file for model and repository libraries Pin
withAnil11-Apr-14 6:30
professionalwithAnil11-Apr-14 6:30 
QuestionStuck on Step 2 Pin
morbicious26-Feb-14 11:08
Membermorbicious26-Feb-14 11:08 
AnswerRe: Stuck on Step 2 Pin
samrobles4-Jun-14 19:04
Membersamrobles4-Jun-14 19:04 
SuggestionExcellent. Would love to see... Pin
GFoley839-Nov-13 13:12
MemberGFoley839-Nov-13 13:12 
QuestionIt's great Pin
Mohammed.Al-Qaisi18-Aug-13 8:27
MemberMohammed.Al-Qaisi18-Aug-13 8:27 
GeneralMy vote of 5 Pin
Srinivas Kalabarigi15-Jul-13 7:55
professionalSrinivas Kalabarigi15-Jul-13 7:55 
QuestionMultiple Database support Pin
sai-krsh15-Jul-13 5:30
Membersai-krsh15-Jul-13 5:30 
GeneralMy vote of 4 Pin
Ashutosh Phoujdar4-Jul-13 0:00
MemberAshutosh Phoujdar4-Jul-13 0:00 
Good work, thanks for sharing.

Your application require more explanation since it is very rich in functionality. Please add more explanation if possible.
QuestionConnectionString Pin
KingR116-Mar-13 6:02
MemberKingR116-Mar-13 6:02 
QuestionError Occured Pin
Ram Nunna10-Mar-13 21:47
professionalRam Nunna10-Mar-13 21:47 
AnswerRe: Error Occured Pin
Anand Ranjan Pandey11-Mar-13 8:43
professionalAnand Ranjan Pandey11-Mar-13 8:43 
QuestionDownloaded on vs2012, EF 5 having compile error Pin
mdelgadov28-Dec-12 7:20
Membermdelgadov28-Dec-12 7:20 
AnswerRe: Downloaded on vs2012, EF 5 having compile error Pin
Anand Ranjan Pandey28-Dec-12 7:54
professionalAnand Ranjan Pandey28-Dec-12 7:54 
GeneralRe: Downloaded on vs2012, EF 5 having compile error Pin
mdelgadov31-Dec-12 8:52
Membermdelgadov31-Dec-12 8:52 
GeneralMy vote of 5 Pin
vdasus28-Nov-12 11:53
Membervdasus28-Nov-12 11:53 
GeneralRe: My vote of 5 Pin
Anand Ranjan Pandey29-Nov-12 2:43
professionalAnand Ranjan Pandey29-Nov-12 2:43 
QuestionShould EDMX be in DAL or MODEL project? Pin
b_77719-Nov-12 11:58
Memberb_77719-Nov-12 11:58 
AnswerRe: Should EDMX be in DAL or MODEL project? Pin
Anand Ranjan Pandey20-Nov-12 5:09
professionalAnand Ranjan Pandey20-Nov-12 5:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.