Showing posts with label ASP.Net MVC. Show all posts
Showing posts with label ASP.Net MVC. Show all posts

Wednesday, 4 May 2016

Areas in ASP.NET MVC

What is an Area in ASP.NET MVC?


Areas are some of the most important components of ASP.NET MVC projects. The main use of Areas are to physically partition web project in separate units.  If you look into an ASP.NET MVC project, logical components like Model, Controller, and the View are kept physically in different folders, and ASP.NET MVC uses naming conventions to create the relationship between these components. Problems start when you have a relatively big application to implement. For instance, if you are implementing an E-Commerce application with multiple business units, such as Checkout, Billing, and Search etc. Each of these units have their own logical components views, controllers, and models. In this scenario, you can use ASP.NET MVC Areas to physically partition the business components in the same project.

In short, an area can be defined as: Smaller functional units in an ASP.NET MVC project with its own set of controllers, views, and models.



A single MVC application may have any number of Areas.  Some of the characteristics of Areas are:

  • An MVC application can have any number of Areas.

  • Each Area has its own controllers, models, and views.

  • Physically, Areas are put under separate folders.

  • Areas are useful in managing big web applications.

  • A web application project can also use Areas from different projects.

  • Using Areas, multiple developers can work on the same web application project.


Creating Areas  


Creating Areas in an MVC project is very simple. Simply right click on the project-> Add->Area as shown in the image below:



Here you will be asked to provide the Area name. In this example, let’s name the Area “Blogs” and click on Add.



Let us stop for a moment here and explore the project. We will find a folder Areas has been added, and inside the Areas folder, we will find a subfolder with the name Blogs, which is the area we just created. Inside the Blogs subfolder, we will find folders for MVC components Controllers, Views, and Models.



In the Area Blogs folder we will find a class BlogAreaRegistration.cs. In this class, routes for the Blog Area have been registered.



Now we can add Controllers, Models, and the Views in the Area in the same way we add them normally in an MVC project. For example, to add a controller, let’s right click on the controller folder in the Blogs folder and click on Add->Controller. So let us say we have added a HomeController in the Blogs controller. You will find the added controller in the project as shown in the image below:



You will find that the HomeController has a method called Index. To create a view, right click on the Index action and select Add View as shown in the image below:



On the next screen, we need to select the view template, model class, and others. To keep things simpler, let us leave everything default and click on the Add button to create a View for the Index action in the Home controller of the Blogs Area.



We will see that a view was created inside the Views subfolder of the Blogs folder as shown in the image below:



To verify, let us go ahead and change the title of the view as shown in the image below:



So far we have created:

  1. An Area with the name Blogs

  2. A controller inside that, named Home

  3. A view for the Index action for the Home controller

  4. Change the title of the view

As a last step to work with Areas, we need to verify whether the Areas are registered in the App_Start of the project or not. To do this, open global.asax and add the highlighted line of code below (if it’s not there already):





Now that we have created the Areas, let us go ahead and run the application and notice the URL.





As highlighted, to invoke the controller of the area, we need to use:

 baseurl/areaname/controllername/{actionname}

In this case Home controller of Blog area is invoked by:

Baseurl/Blogs/Home/Index

Summary


As you’ve seen here, Areas are some of the most important components of ASP.NET MVC, allowing us to break big projects into smaller, more manageable units, as demonstrated in this blog’s example. I hope you find the post useful, and thanks for reading!

How to Create a Custom Action Filter in ASP.NET MVC

In ASP.NET MVC, Filters are used to inject logic at different levels of request processing and allow us to share logics across Controllers. For example, let’s say we want to run a security logic or a logging logic across the controller. To do so, we’ll write a filter containing those logics and enable them across all controllers. When we enable a filter across all controllers or actions, the filter enables the upcoming HTTP request.

Let us consider a scenario of Logging: for every incoming request, we need to log some data to the files on the basis of some logic. If we don’t create this logic inside a custom filter, then we will have to write logic for each controller’s action. This mechanism will lead to two problems:

  1. duplication of code; and

  2. violation of the Single Responsibility Principles; actions will now perform additional tasks of logging.

We can mitigate the problems above by putting the logging logics inside a custom action filter and applying the filter at all the controllers’ level.

Have you ever come across source code as shown in the image below? [Authorize] is an Authorization filter, and it gets executed before any HTPP request or Action method execution.  The Authorize filter is part of MVC, but if needed, we can create a custom filter too.



In ASP.NET MVC, there are four types of filters:

  1. Authentication Filter

  2. Authorization Filter

  3. Action Filter

  4. Result Filter

  5. Exception Filter

The sequence of running of various filters are as follows:

  • The Authentication filter runs before any other filter or action method

  • The Authorization filter runs after the Authentication filter and before any other filter or action method

  • The Action filter runs before and after any action method

  • The Result filter runs before and after execution of any action result

  • The Exception filter runs only if action methods, filters or action results throw an exception

In a diagram, we can depict the sequence of filter execution as shown below:



Each filter has its own purposes, however most of the time you will find yourself writing a Custom Action Filter. They get executed before and after execution of an action.

Custom Action Filter

We write custom action filters for various reasons. We may have a custom action filter for logging, or for saving data to database before any action execution. We could also have one for fetching data from the database and setting it as the global values of the application. We can create custom action filters for various reasons including but not limited to:

  • Creating a privileged authorization

  • Logging the user request

  • Pre-processing image upload

  • Fetching data to display in the layout menu

  • Localization of the application

  • Reading browser user agent information to perform a particular task

  • Caching, etc.

To create a custom action filter, we need to perform the following tasks:

  1. Create a class

  2. Inherit it from ActionFilterAttribute class

  3. Override at least one of the following methods:


  • OnActionExecuting – This method is called before a controller action is executed.

  • OnActionExecuted – This method is called after a controller action is executed.

  • OnResultExecuting – This method is called before a controller action result is executed.

  • OnResultExecuted – This method is called after a controller action result is executed.

Let us create a custom action filter which will perform two tasks, in the most simplistic way. Of course you can write more sophisticated code inside the custom action filter, but we are going to create a custom filter with the name MyFirstCustomFilter, which will perform the following two tasks:

  1. Set some data value in global ViewBag.

  2. Log the incoming request to the controller action method.

The filter can be created as shown in the listing below:

using System;
using System.Diagnostics;
using System.Web.Mvc;

namespace WebApplication1
{
    public class MyFirstCustomFilter : ActionFilterAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            //You may fetch data from database here 
            filterContext.Controller.ViewBag.GreetMesssage = "Hello Foo";
            base.OnResultExecuting(filterContext);
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var controllerName = filterContext.RouteData.Values["controller"];
            var actionName = filterContext.RouteData.Values["action"];
            var message = String.Format("{0} controller:{1} action:{2}", "onactionexecuting", controllerName, actionName);
            Debug.WriteLine(message, "Action Filter Log");
            base.OnActionExecuting(filterContext);
        }
    }
}


In the above listing, we are simply setting ViewBag property for the controllers being executed. The ViewBag property will be set before a controller action result is executed, since we are overriding the OnResultExecuting method. Also, we are overriding OnActionExecuting to log the information about controller’s action method.

So now we’ve created the custom action filter. Now we can apply that at three possible levels:

  • As a Global filter

  • At a Controller level

  • At an Action level

Applying as a Global Filter

We can apply a custom filter at a global level by adding a filter to the global filter inApp_Start\FilterConfig. Once added at the global level, the filter would be available for all the controllers in the MVC application.

public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new MyFirstCustomFilter());
        }
    }


Filter at a Controller level

To apply a filter at the controller level, we can apply it as an attribute to a particular controller. When applied as controller level, the action would be available to all the actions of the particular controller. We can apply MyFirstCustomFilter to HomeController as shown in the listing below:

[MyFirstCustomFilter]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
     }


Filter at an Action level

Finally, to apply a filter at a particular action, we can apply it as an attribute of the Action as shown in the listing below:

[MyFirstCustomFilter]
        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }


And that’s about it for custom action filters! I hope you find this post useful, and thanks for reading. Have something to add? Feel free to leave a comment!

Saturday, 16 April 2016

What is Code-First

Entity Framework introduced Code-First approach from Entity Framework 4.1. Code-First is mainly useful in Domain Driven Design. With the Code-First approach, you can focus on the domain design and start creating classes as per your domain requirement rather than design your database first and then create the classes which match your database design. Code-First APIs will create the database on the fly based on your entity classes and configuration.


code-first in entity framework
As a developer, you first start by writing C# or VB.net classes and context class. When you run the application, Code First APIs will create the new database (if it does not exist yet) and map your classes with the database using default code-first conventions. You can also configure your domain classes to override default conventions to map with database tables using DataAnnotation attributes or fluent API.

The basic workflow would be:

Write application domain classes and context class→ configure domain classes for additional mapping requirements → Hit F5 to run the application → Code First API creates new database or map existing database with domain classes → Seed default/test data into the database → Finally launches the application

Monday, 11 April 2016

Difference between ASP.NET MVC and ASP.NET Web API

While developing your web application using MVC, many developers got confused when to use Web API, since MVC framework can also return JSON data by using JsonResult and can also handle simple AJAX requests. In previous article, I have explained the Difference between WCF and Web API and WCF REST and Web Service and when to use Web API over others services. In this article, you will learn when to use Web API with MVC.

Asp.Net Web API VS Asp.Net MVC



  1. Asp.Net MVC is used to create web applications that returns both views and data but Asp.Net Web API is used to create full blown HTTP services with easy and simple way that returns only data not view.

  2. Web API helps to build REST-ful services over the .NET Framework and it also support content-negotiation(it's about deciding the best response format data that could be acceptable by the client. it could be JSON,XML,ATOM or other formatted data), self hosting which are not in MVC.

  3. Web API also takes care of returning data in particular format like JSON,XML or any other based upon the Accept header in the request and you don't worry about that. MVC only return data in JSON format using JsonResult.

  4. In Web API the request are mapped to the actions based on HTTP verbs but in MVC it is mapped to actions name.

  5. Asp.Net Web API is new framework and part of the core ASP.NET framework. The model binding, filters, routing and others MVC features exist in Web API are different from MVC and exists in the new System.Web.Httpassembly. In MVC, these featues exist with in System.Web.Mvc. Hence Web API can also be used with Asp.Net and as a stand alone service layer.

  6. You can mix Web API and MVC controller in a single project to handle advanced AJAX requests which may return data in JSON, XML or any others format and building a full blown HTTP service. Typically, this will be called Web API self hosting.

  7. When you have mixed MVC and Web API controller and you want to implement the authorization then you have to create two filters one for MVC and another for Web API since boths are different.

  8. Moreover, Web API is light weight architecture and except the web application it can also be used with smart phone apps.


What do you think?

I hope you have got when to use Web API over MVC and how it works. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

Comparing Asp.Net Web API Routing and Asp.Net MVC Routing

As you know, Routing is a pattern matching system that monitor the incoming request and figure out what to do with that request. A URL pattern is matched against the routes patterns defined in the Route dictionary in an Order and the first match wins. This means the first route which successfully matches a controller, action, and action parameters defined in the URL will call into the specified controller and action.


Asp.Net MVC application and Asp.Net Web API must have at least one route defined in order to function. Hence, Visual Studio templates defined for MVC and Web API must have a default route. Now let's understand the difference between Asp.Net MVC and Asp.Net Web API.

Default Route Pattern


The default route pattern for a Web API Project is defined as follows-

  1. config.Routes.MapHttpRoute(

  2. name: "DefaultApi", //route name

  3. routeTemplate: "api/{controller}/{id}", //route pattern

  4. defaults: new { id = RouteParameter.Optional } //parameter default values

  5. );


The literal api at the beginning of the Web API route pattern, makes it distinct from the standard MVC route. This is not mandatory but it is a good convention to differ Web API route from MVC route.

In Web API route pattern {action} parameter is optional but you can include an {action} parameter. Also, the action methods defined on the controller must be have an HTTP action verb as a prefix to the method name in order to work. So, you can also define the route for Web API as follows-

  1. config.Routes.MapHttpRoute(

  2. name: "DefaultApi",//route name

  3. routeTemplate: "api/{controller}/{action}/{id}",//route pattern

  4. defaults: new { id = RouteParameter.Optional }//parameter default values

  5. );


The default route pattern for an Asp.Net MVC Project is defined as follows-

  1. routes.MapRoute(

  2. name: "Default", //route name

  3. url: "{controller}/{action}/{id}", //route pattern

  4. defaults: new

  5. {

  6. controller = "Home",

  7. action = "Index",

  8. id = UrlParameter.Optional

  9. } //parameter default values

  10. );


As you have seen there is no literal before at the beginning of the Asp.Net MVC route pattern but you can add if you wish.

Route Processing


In Web API route processing the URLs map to a controller, and then to the action which matches the HTTP verb of the request and the most parameters of the request is selected. The Action methods defined in the API controller must either have the HTTP action verbs (GET, POST, PUT, DELETE) or have one of the HTTP action verbs as a prefix for the Actions methods name as given below-

  1. public class ValuesController : ApiController

  2. {

  3. // GET api/

  4. public IEnumerable Get()

  5. {

  6. return new string[] { "value1", "value2" };

  7. }


  8. // GET api//5

  9. public string Get(int id)

  10. {

  11. return "value";

  12. }


  13. // POST api/

  14. public void Post([FromBody]string value)

  15. {

  16. }


  17. // PUT api//5

  18. public void Put(int id, [FromBody]string value)

  19. {

  20. }


  21. // DELETE api//5

  22. public void Delete(int id)

  23. {

  24. }

  25. }


  26. // OR You can also defined above API Controller as Verb Prefix


  27. public class ValuesController : ApiController

  28. {

  29. // GET api/values

  30. public IEnumerable GetValues()

  31. {

  32. return new string[] { "value1", "value2" };

  33. }

  34. // GET api/values/5

  35. public string GetValues(int id)

  36. {

  37. return "value";

  38. }

  39. // POST api/values

  40. public void PostValues([FromBody]string value)

  41. {

  42. }

  43. // PUT api/values/5

  44. public void PutValues(int id, [FromBody]string value)

  45. {

  46. }

  47. // DELETE api/values/5

  48. public void DeleteValues(int id)

  49. {

  50. }

  51. }


In Asp.Net MVC route processing the URLs map to a controller, and then to the action which matches the HTTP verb of the request and the most parameters of the request is selected. The Action methods defined in the MVC controller do not have HTTP action verbs as a prefix for the Actions methods but they have name like as normal method as shown below-

  1. public class HomeController : Controller

  2. {

  3. // GET: /Home/Index

  4. public ActionResult Index() //method - Index

  5. {

  6. // To Do:

  7. return View();

  8. }

  9.  

  10. // Post: /Home/Index

  11. [HttpPost]

  12. public ActionResult Index(LoginModel model, string id)

  13. {

  14. // To Do:

  15. return View();

  16. }

  17. }


In MVC, by default HTTP verb is GET for using others HTTP verbs you need defined as an attribute but in Web API you need to define as an method's name prefix.

Complex Parameter Processing


Unlike MVC, URLs in Web API cannot contain complex types. Complex types must be placed in the HTTP message body and there should be only one complex type in the body of an HTTP message.

Base Library


Web API controllers inherit from System.Web.Http.Controller, but MVC controllers inherit fromSystem.Web.Mvc.Controller. Both the library are different but acts in similar fashion.
What do you think?

I hope you will enjoy the tips while programming with Asp.Net MVC and Web API. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

Tuesday, 5 April 2016

ViewData vs ViewBag vs TempData vs Session

In ASP.NET MVC there are three ways - ViewData, ViewBag and TempData to pass data from controller to view and in next request. Like WebForm, you can also use Session to persist data during a user session. Now question is that when to use ViewData, VieBag, TempData and Session. Each of them has its own importance. In this article, I am trying to explain the differences among these four.


ViewData



  1. ViewData is a dictionary object that is derived from ViewDataDictionary class.

    1. public ViewDataDictionary ViewData { get; set; }

  2. ViewData is a property of ControllerBase class.

  3. ViewData is used to pass data from controller to corresponding view.

  4. It’s life lies only during the current request.

  5. If redirection occurs then it’s value becomes null.

  6. It’s required typecasting for getting data and check for null values to avoid error.

ViewBag



  1. ViewBag is a dynamic property that takes advantage of the new dynamic features in C# 4.0.

  2. Basically it is a wrapper around the ViewData and also used to pass data from controller to corresponding view.

    1. public Object ViewBag { get; }

  3. ViewBag is a property of ControllerBase class.

  4. It’s life also lies only during the current request.

  5. If redirection occurs then it’s value becomes null.

  6. It doesn’t required typecasting for getting data.

TempData



  1. TempData is a dictionary object that is derived from TempDataDictionary class and stored in short lives session.

    1. public TempDataDictionary TempData { get; set; }

  2. TempData is a property of ControllerBase class.

  3. TempData is used to pass data from current request to subsequent request (means redirecting from one page to another).

  4. It’s life is very short and lies only till the target view is fully loaded.

  5. It’s required typecasting for getting data and check for null values to avoid error.

  6. It is used to store only one time messages like error messages, validation messages.

Session



  1. In ASP.NET MVC, Session is a property of Controller class whose type is HttpSessionStateBase.

    1. public HttpSessionStateBase Session { get; }

  2. Session is also used to pass data within the ASP.NET MVC application and Unlike TempData, it persists for its expiration time (by default session expiration time is 20 minutes but it can be increased).

  3. Session is valid for all requests, not for a single redirect.

  4. It’s also required typecasting for getting data and check for null values to avoid error.

Summary

In this article I try to explain the difference between ViewData, ViewBag and TempData. I hope you will refer this article for your need. I would like to have feedback from my blog readers. Please post your feedback, question, or comments about this article.

Monday, 4 April 2016

How to Implement the Repository Pattern in ASP.NET MVC Application

The Repository Pattern is one of the most popular patterns to create an enterprise level application. It restricts us to work directly with the data in the application and creates new layers for database operations, business logic and the application’s UI. If an application does not follow the Repository Pattern, it may have the following problems:

  • Duplicate database operations codes

  • Need of UI to unit test database operations and business logic

  • Need of External dependencies to unit test business logic

  • Difficult to implement database caching, etc.

Using the Repository Pattern has many advantages:

  • Your business logic can be unit tested without data access logic;

  • The database access code can be reused;

  • Your database access code is centrally managed so easy to implement any database access policies, like caching;

  • It’s easy to implement domain logics;

  • Your domain entities or business entities are strongly typed with annotations; and more.

On the internet, there are millions of articles written around Repository Pattern, but in this one we’re going to focus on how to implement it in an ASP.NET MVC Application. So let’s get started!

Project Structure

Let us start with creating the Project structure for the application. We are going to create four projects:

  1. Core Project

  2. Infrastructure Project

  3. Test Project

  4. MVC Project

Each project has its own purpose. You can probably guess by the projects’ names what they’ll contain: Core and Infrastructure projects are Class Libraries, Web project is a MVC project, and Test project is a Unit Test project. Eventually, the projects in the solution explorer will look as shown in the image below:



As we progress in this post, we will learn in detail about the purpose of each project, however, to start we can summarize the main objective of each project as the following:



So far our understanding for different projects is clear. Now let us go ahead and implement each project one by one. During the implementations, we will explore the responsibilities of each project in detail.



Core Project

In the core project, we keep the entities and the repository interfaces or the database operation interfaces. The core project contains information about the domain entities and the database operations required on the domain entities. In an ideal scenario, the core project should not have any dependencies on external libraries. It must not have any business logic, database operation codes etc.

In short, the core project should contain:

  • Domain entities

  • Repository interfaces or database operations interfaces on domain entities

  • Domain specific data annotations

The core project can NOT contain:

  • Any external libraries for database operations

  • Business logic

  • Database operations code

While creating the domain entities, we also need to make a decision on the restrictions on the domain entities properties, for example:

  • Whether a particular property is required or not. For instance, for a Product entity, the name of the product should be required property.

  • Whether a value of a particular property is in given range or not. For instance, for a Product entity, the price property should be in given range.

  • Whether the maximum length of a particular property should not be given value. For instance, for a Product entity, the name property value should be less than the maximum length.

There could be many such data annotations on the domain entities properties. There are two ways we can think about these data annotations:

  1. As part of the domain entities

  2. As part of the database operations logic

It is purely up to us how we see data annotations. If we consider them part of database operation then we can apply restrictions using database operation libraries API. We are going to use the Entity Framework for database operations in the Infrastructure project, so we can use Entity Framework Fluent API to annotate data.

If we consider them part of domain, then we can use System.ComponentModel.DataAnnotationslibrary to annotate the data. To use this, right click on the Core project’s Reference folder and click on Add Reference. From the Framework tab, selectSystem.ComponentModel.DataAnnotations and add to the project.

We are creating a ProductApp, so let us start with creating the Product entity. To add an entity class, right click on the Core project and add a class, then name the class Product.

using System.ComponentModel.DataAnnotations;
namespace ProductApp.Core
{
    public class Product
    {
        public int Id { get; set; }
 [Required]
 [MaxLength(100)]
        public string Name { get; set; }
 [Required]
        public double Price { get; set; }
        public bool inStock { get; set; }
    }
}


We have annotated the Product entity properties with Required and MaxLength. Both of these annotations are part of System.ComponentModel.DataAnnotations. Here, we have considered restriction as part of the domain, hence used data annotations in the core project itself.

We have created Product Entity class and also applied data annotation to that. Now let us go ahead and create Repository interface. But before we create that, let us understand, what is a Repository Interface?

The repository interface defines all the database operations possible on the domain entities. All database operations that can be performed on the domain entities are part of the domain information, hence we will put the repository interface in the core project. How these operations can be performed will be the part of Infrastructure project.

To create a Repository Interface, right click on the Core project and add a folder named Interfaces. Once the Interfaces folder is created, right click on the Interface folder and select add a new item, then from the Code tab select Interface. Name the Interface IProductRepository

using System.Collections.Generic;

namespace ProductApp.Core.Interfaces
{
    public interface IProductRepository
    {
        void Add(Product p);
        void Edit(Product p);
        void Remove(int Id);
        IEnumerable GetProducts(); Product FindById(int Id); } }


Now we have created a Product entity class and a Product Repository Interface. At this point, the core project should look like this:



Let us go ahead and build the core project to verify everything is in place and move ahead to create Infrastructure project.



Infrastructure Project

Main purpose of Infrastructure project is to perform database operations. Besides database operations, it can also consume web services, perform IO operations etc. So mainly, Infrastructure project may perform the following operations:

  • Database operations

  • Working with WCF and Web Services

  • IO operations

We can use any database technology to perform database operations. In this post we are going to use Entity Framework. So we are going to create database using the Code First approach. In the Code First approach, database gets created on basis of the classes. Here database will be created on the basis of the Domain entities from the Core Project.

To create the database from the Core project domain entity, we need to perform these tasks:

  1. Create DataContext class

  2. Configure the connection string

  3. Create DataBase Initalizer class to seed data in the database

  4. Implement IProductRepsitory interface



Adding References

First let’s add references of the Entity Framework and ProductApp.Core project. To add the Entity Framework, right click on the Infrastructure project and click on Manage Nuget Package. In the Package Manager Window, search for Entity Framework and install the latest stable version.

To add a reference of the ProductApp.Core project, right click on the Infrastructure project and click on Add Reference. In the Reference Window, click on the Project tab and select ProductApp.Core.

DataContext class

The objective of the DataContext class is to create the DataBase in the Entity Framework Code First approach. We pass a connection string in the constructor of DataContext class. By reading the connection string, the Entity Framework create the database. If a connection string is not specified then the Entity Framework creates the database in a local database server.

In the DataContext class:

  • Create a DbSet type property. This is responsible for creating the table for the Product entity

  • In the constructor of the DataContext class, pass the connection string to specify information to create database, for example server name, database name, login information etc. We need to pass name of the connection string. name where database would be created

  • If connection string is not passed, Entity Framework creates with the name of data context class in the local database server.

  • ProductDataContext class inherits the DbContext class

The ProductDataContext class can be created as shown in the listing below:

using ProductApp.Core;
using System.Data.Entity;

namespace ProductApp.Infrastructure
{
    public class ProductContext  : DbContext
    {
        public ProductContext()
           : base("name=ProductAppConnectionString")
       {
       }
        public DbSet Products { get; set; } } }


Next we need to work on the Connection String. As discussed earlier, we can either pass the connection string to specify database creation information or reply on the Entity Framework to create default database at default location for us. We are going to specify the connection string that is why, we passed a connection string name ProductAppConnectionString in the constructor of ProductDataContext class. In the App.Config file the ProductAppConnectionString connection string can be created as shown in the listing below:

  
  <add name="ProductAppConnectionString" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ProductAppJan;Integrated Security=True;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>


Database Initializer class

We create a database initializer class to seed the database with some initial value at time of the creation. To create the Database initializer class, create a class which inherits fromDropCreateDatabaseIfModelChnages. There are other options of classes available to inherit in order to create a database initializer class. If we inherit DropCreateDatabaseIfModelChnages class then each time a new database will be created on the model changes. So for example, if we add or remove properties from the Product entity class, Entity Framework will drop the existing database and create a new one. Of course this is not a great option, since data will be lost too, so I recommend you explore other options to inherit the database initializer class.

The database initializer class can be created as shown in the listing below. Here we are seeding the product table with two rows. To seed the data:

  1. Override Seed method

  2. Add product to Context.Products

  3. Call Context.SaveChanges()


using ProductApp.Core;
using System.Data.Entity;

namespace ProductApp.Infrastructure
{
    public class ProductInitalizeDB : DropCreateDatabaseIfModelChanges { protected override void Seed(ProductContext context) { context.Products.Add(new Product { Id = 1, Name = "Rice", inStock = true, Price = 30 }); context.Products.Add(new Product { Id = 2, Name = "Sugar", inStock = false, Price = 40 }); context.SaveChanges(); base.Seed(context); } } }


So far, we have done all the Entity Framework Code First related work to create the database. Now let’s go ahead and implement IProductRepository interface from the Core project in a concrete ProductRepository class.



Repository Class

This is the class which will perform database operations on the Product Entity. In this class, we will implement the IProductRepository interface from the Core project. Let us start with adding a class ProductRepository to the Infrastructure project and implement IProductRepository interface. To perform database operations, we are going to write simple LINQ to Entity queries. ProductRepositry class can be created as shown in the listing below:

using ProductApp.Core.Interfaces;
using System.Collections.Generic;
using System.Linq;
using ProductApp.Core;

namespace ProductApp.Infrastructure
{
    public class ProductRepository : IProductRepository
    {
        ProductContext context = new ProductContext();
        public void Add(Product p)
        {
            context.Products.Add(p);
            context.SaveChanges();
        }

        public void Edit(Product p)
        {
            context.Entry(p).State = System.Data.Entity.EntityState.Modified;
        }

        public Product FindById(int Id)
        {
            var result = (from r in context.Products where r.Id == Id select r).FirstOrDefault();
            return result;
        }

        public IEnumerable GetProducts() { return context.Products; } public void Remove(int Id) { Product p = context.Products.Find(Id); context.Products.Remove(p); context.SaveChanges(); } } }


So far we have created a Data Context class, a Database Initializer class, and the Repository class. Let us build the infrastructure project to make sure that everything is in place. The ProductApp.Infrastructure project will look as given in the below image:



Now we’re done creating the Infrastructure project. We have written all the database operations-related classes inside the Infrastructure project, and all the database-related logic is in a central place. Whenever any changes in database logic is required, we need to change only the infrastructure project.



Test Project

The biggest advantage of Repository Pattern is the testability. This allows us to unit test the various components without having dependencies on other components of the project. For example, we have created the Repository class which performs the database operations to verify correctness of the functionality, so we should unit test it. We should also be able to write tests for the Repository class without any dependency on the web project or UI. Since we are following the Repository Pattern, we can write Unit Tests for the Infrastructure project without any dependency on the MVC project (UI).

To write Unit Tests for ProductRepository class, let us add following references in the Test project.

  1. Reference of ProductApp.Core project

  2. Reference of ProductApp.Infrastructure project

  3. Entity Framework package



To add the Entity Framework, right click on the Test project and click on Manage Nuget Package. In the Package Manger Windows, search for Entity Framework and install the latest stable version.

To add a reference of the ProductApp.Core project, right click on the Test project and click on Add Reference. In the Reference Window, click on Project tab and select ProductApp.Core.

To add a reference of the ProductApp.Infrastructure project, right click on the Test project and click on Add Reference. In the Reference Window, click on Project tab and select ProductApp.Infrastructure.

Copy the Connection String

Visual Studio always reads the config file of the running project. To test the Infrastructure project, we will run the Test project. Hence the connection string should be part of the App.Config of the Test project. Let us copy and paste the connection string from Infrastructure project in the Test project.

We have added all the required references and copied the connection string. Let’s go ahead now and set up the Test Class. We’ll create a Test Class with the name ProductRepositoryTest. Test Initialize is the function executed before the tests are executed. We need to create instance of the ProductRepository class and call the ProductDbInitalize class to seed the data before we run tests. Test Initializer can be written as shown in the listing below:

[TestClass]
    public class ProductRepositoryTest
    {
        ProductRepository Repo; 
 [TestInitialize]
        public void TestSetup()
        {
            ProductInitalizeDB db = new ProductInitalizeDB();
            System.Data.Entity.Database.SetInitializer(db);
            Repo = new ProductRepository();
        }
    }


Now we’ve written the Test Initializer. Now let write the very first test to verify whether ProductInitalizeDB class seeds two rows in the Product table or not. Since it is the first test we will execute, it will also verify whether the database gets created or not. So essentially we are writing a test:

  1. To verify database creation

  2. To verify number of rows inserted by the seed method of Product Database Initializer


[TestMethod]
        public void IsRepositoryInitalizeWithValidNumberOfData()
        {
            var result = Repo.GetProducts();
            Assert.IsNotNull(result);
            var numberOfRecords = result.ToList().Count;
            Assert.AreEqual(2, numberOfRecords);
        }


As you can see, we’re calling the Repository GetProducts() function to fetch all the Products inserted while creating the database. This test is actually verifying whether GetProducts() works as expected or not, and also verifying database creation. In the Test Explorer window, we can run the test for verification.



To run the test, first build the Test project, then from the top menu select Test->Windows-Test Explorer. In the Test Explorer, we will find all the tests listed. Select the test and click on Run.

Let’s go ahead and write one more test to verify Add Product operation on the Repository:

 [TestMethod]
        public void IsRepositoryAddsProduct()
        {
            Product productToInsert = new Product
            {
                Id = 3,
                inStock = true,
                Name = "Salt",
                Price = 17

            };
            Repo.Add(productToInsert);
            // If Product inserts successfully, 
            //number of records will increase to 3 
            var result = Repo.GetProducts();
            var numberOfRecords = result.ToList().Count;
            Assert.AreEqual(3, numberOfRecords);
        }


To verify insertion of the Product, we are calling the Add function on the Repository. If Product gets added successfully, the number of records will increase to 3 from 2 and we are verifying that. On running the test, we will find that the test has been passed.



In this way, we can write tests for all the Database operations from the Product Repository class. Now we are sure that we have implemented the Repository class correctly because tests are passing, which means the Infrastructure and Core project can be used with any UI (in this case MVC) project.



MVC or Web Project

Finally we have gotten to the MVC project! Like the Test project, we need to add following references

  1. Reference of ProductApp.Core project

  2. Reference of ProductApp.Infrastructure project

To add a reference of the ProductApp.Core project, right click on the MVC project and click on Add Reference. In the Reference Window, click on Project tab and select ProductApp.Core.

To add a reference of the ProductApp.Infrastructure project, right click on the MVC project and click on Add Reference. In the Reference Window, click on Project tab and select ProductApp.Infrastructure.



Copy the Connection String

Visual Studio always reads the config file of the running project. To test the Infrastructure project, we will run the Test project, so the connection string should be part of the App.Config of the Test project. To make it easier, let’s copy and paste the connection string from Infrastructure project in the Test project.



Scaffolding the Application

We should have everything in place to scaffold the MVC controller. To scaffold, right click on the Controller folder and select MVC 5 Controller with Views, using Entity Framework as shown in the image below:



Next we will see the Add Controller window. Here we need to provide the Model Class and Data context class information. In our project, model class is the Product class from the Core project and the Data context class is the ProductDataContext class from the Infrastructure project. Let us select both the classes from the dropdown as shown in the image below:



Also we should make sure that the Generate Views, Reference script libraries, and Use a layout page options are selected.

On clicking Add, Visual Studio will create the ProductsController and Views inside Views/Products folder. The MVC project should have structure as shown in the image below:



At this point if we go ahead and run the application, we will be able to perform CRUD operations on the Product entity.



Problem with Scaffolding

But we are not done yet! Let’s open the ProductsController class and examine the code. On the very first line, we will find the problem. Since we have used MVC scaffolding, MVC is creating an object of the ProductContext class to perform the database operations.



Any dependencies on the context class binds the UI project and the Database tightly to each other. As we know the Datacontext class is an Entity Framework component. We do not want the MVC project to know which database technology is being used in the Infrastructure project. On the other hand, we haven’t tested the Datacontext class; we’ve tested the ProductRepository class. Ideally we should use ProductRepository class instead of the ProductContext class to perform database operations in the MVC Controller.  To summarize,

  1. MVC Scaffolding uses Data context class to perform database operations. The data context class is an Entity Framework component, so its uses tightly couples UI (MVC) with the Database (EF) technology.

  2. The data context class is not unit tested so it’s not a good idea to use that.

  3. We have a tested ProductRepository class. We should use this inside Controller to perform database operations. Also, the ProductRepository class does not expose database technology to the UI.

To use the ProductRepository class for database operations, we need to refactor the ProductsController class. To do so, there are two steps we need to follow:

  1. Create an object of ProductRepository class instead of ProductContext class.

  2. Call methods of ProductRepository class to perform database operations on Product entity instead of methods of ProductContext class.

In the listing below, I have commented codes using ProductContext and called ProductRepository methods. After refactoring, the ProductController class will look like the following:

using System;
using System.Net;
using System.Web.Mvc;
using ProductApp.Core;
using ProductApp.Infrastructure;

namespace ProductApp.Web.Controllers
{
    public class ProductsController : Controller
    {
        //private ProductContext db = new ProductContext();
        private ProductRepository db = new ProductRepository();

     
        public ActionResult Index()
        {
            //return View(db.Products.ToList());
            return View(db.GetProducts());
        }

    
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            // Product product = db.Products.Find(id);
            Product product = db.FindById(Convert.ToInt32(id));
            if (product == null)
            {
                return HttpNotFound();
            }
            return View(product);
        }

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

 [HttpPost]
 [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Name,Price,inStock")] Product product)
        {
            if (ModelState.IsValid)
            {
                // db.Products.Add(product);
                //db.SaveChanges();
                db.Add(product);
                return RedirectToAction("Index");
            }

            return View(product);
        }

       
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Product product = db.FindById(Convert.ToInt32(id));
            if (product == null)
            {
                return HttpNotFound();
            }
            return View(product);
        }

 [HttpPost]
 [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Name,Price,inStock")] Product product)
        {
            if (ModelState.IsValid)
            {
                //db.Entry(product).State = EntityState.Modified;
                //db.SaveChanges();
                db.Edit(product);
                return RedirectToAction("Index");
            }
            return View(product);
        }

   
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Product product = db.FindById(Convert.ToInt32(id));
            if (product == null)
            {
                return HttpNotFound();
            }
            return View(product);
        }

 
 [HttpPost, ActionName("Delete")]
 [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            //Product product = db.FindById(Convert.ToInt32(id));
            // db.Products.Remove(product);
            // db.SaveChanges();
            db.Remove(id);
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                //db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}


After refactoring, let’s go ahead and build and run the application – we should be able to do so and perform the CRUD operations.

Injecting the Dependency

Now we’re happy that the application is up and running, and it was created using the Repository pattern. But still there is a problem: we are directly creating an object of the ProductRepository class inside the ProductsController class, and we don’t want this. We want to invert the dependency and delegate the task of injecting the dependency to a third party, popularly known as a DI container. Essentially, ProductsController will ask the DI container to return the instance of IProductRepository.

There are many DI containers available for MVC applications. In this example we’ll use the simplest Unity DI container. To do so, right click on the MVC project and click Manage Nuget Package. In the Nuget Package Manager search for Unity.Mvc and install the package.



Once the Unity.Mvc package is installed, let us go ahead and open App_Start folder. Inside the App_Start folder, we will find the UnityConfig.cs file. In the UnityConfig class, we havr to register the type. To do so, open RegisterTypes function in UnityConfig class and register the type as shown in the listing below:

public static void RegisterTypes(IUnityContainer container)
        {
            

            // TODO: Register your types here
            container.RegisterType(); }


We have registered the type to Unity DI container. Now let us go ahead and do a little bit of refactoring in the ProductsController class.  In the constructor of ProductsController we will pass the reference of the repository interface. Whenever required by the application, the Unity DI container will inject the concrete object of ProductRepository in the application by resolving the type. We need to refactor the ProductsController as shown in the listing below:

  public class ProductsController : Controller
    {
        IProductRepository db;
        public ProductsController(IProductRepository db)
        {

            this.db = db;
        }


Let us go ahead and build and run the application. We should have the application up and running, and we should able to perform CRUD operations using Repository Pattern and Dependency Injection!

Conclusion

In this article, we learned in a step by step manner how to create an MVC application following the Repository pattern. In doing so, we can put all the database logic in one place and whenever required, we only need to change the repository and test that. The Repository Pattern also loosely couples the application UI with the Database logic and the Domain entities and makes your application more testable.

I hope you found this post useful, thanks for reading!