2 . ASP.NET MVC4 Industrial Strength Applications

About this Tutorial

Objectives

Delegates will learn to develop web applications using MVC. After completing this course, delegates will be able to:

  • Use Visual Studio 2012 effectively
  • Create commercial ASP.NET Web Applications
  • Develop user interfaces using Master Pages, Site Navigation and Themes

Audience

This course has been designed primarily for programmers new to the .Net development platform. Delegates experience solely in Windows application development or earlier versions of ASP.Net will also find the content beneficial.

Prerequisites

No previous experience in ASP.NET programming is required. But any experience you do have in programming will help. Also no experience in visual studio is required. But again any experience you do have with programming development environments will be a valuable.

Download Solutions

HTML tutorial


OverviewEstimated Time – 3 hours and 30 minutes

Not what you are looking? Try the next tutorial – ASP.NET MVC4 Test Driven Development

In this tutorial we will enhance the the film application you last worked on in the tutorial “Creating an ASP.NET MVC 4 Application”

In these labs, we’ll see how to create industrial-strength ASP.NET MVC applications

FinshedApplication

  1. The application will be a film rental web application.
  2. At the end of the tutorial the application will display a list of film titles.
  3. The underlying architecture is the important aspect.

How about a training course? View Course Outline.

Lab 1: Creating the Application

Lab 1: Creating the Application
    1. Create the ASP.NET MVC 4 web application named FilmsRUsOnline using C#. Make sure to choose Internet Application and use the Razor engine. Also create a unit test project and name this FilmsRUsOnline.Tests.

CreatingApp

  1. Add a C# class library project to the solution; this is done by right clicking the solution, select Add, then New Project, and under Visual C# choose class library and name this Domain; You can then delete the file Class1.cs.

Lab 2: Defining a Domain Model

Lab 2: Defining a Domain Model
    1. In a large-scale application, the real business logic will probably reside in external class libraries, so we create two folders in Domain one called Entities and the other called Repositories. Make sure both folders are in our Domain project.
    2. To create the folders right click on Domain and choose Add>New Folder and rename them as above.
    3. In the Entities folder add a new class by right clicking on Entities, selecting Add>Class and name this Film.

ASP.NET

  1. Now the class has been created; we need an entity class to represent information about a film and this must be public, so as to be accessed by other assemblies.
    namespace Domain.Entities
    {
    public class Film
    {
    public int FilmID { get; set; }
    public string Title { get; set; }
    public string Blurb { get; set; }
    public string Genre { get; set; }
    public decimal RentalPrice { get; set; }
    }
    }
  2. View code file.
  3. In a typical application, domain entities are persisted to a data source e.g. a database. It’s good practice to define separate “repository” classes to manage this persistence. It’s also good practice to define an interface for the repository e.g. for talking to a database or a fixed data set.
  4. Here is the Film Repository called IFilmsRepository.
    using Domain.Entities;
    namespace Domain.Repositories
    {
    public interface IFilmsRepository
    {
    IList Films { get; }
    }
    }
  5. View code file.
  6. Here is a dummy repository to use, it allows you to start testing straight away. Its called DummyFilmsRepository. If you look in the code you will notice that the class is implementing the interface IFilmsRepository; this contains its own private variables and the properties to expose a list of films.
    using Domain.Entities;
    namespace Domain.Repositories
    {
    public class DummyFilmsRepository : IFilmsRepository
    {
    // Dummy (hard-coded) list of films.
    private static IList dummyFilms = new List {
    new Film { Title="Airplane", Blurb="Classic spoof airline disaster movie",
    Genre="Comedy", RentalPrice=1.50m },
    new Film { Title="Jaws", Blurb="Shark-fest film that spooked a generation",
    Genre="Thriller", RentalPrice=1.99m },
    new Film { Title="Love Actually", Blurb="Feel-good family entertainment",
    Genre="RomCom", RentalPrice=2.99m },
    };
    // Returns dummy (hard-coded) list of films.
    public IList Films
    {
    get { return dummyFilms; }
    }
    }
    }
  7. View code file.

Lab 3: Defining the Web Application

Lab 3: Defining the Web Application
    1. Add a controller class named FilmController to the Controllers folder. To do this right-click in Solution Explorer and select Add>Controller from the context menu.
    2. Include a reference to the Domain by right clicking on the project FilmsRUsOnline and selecting Add Reference>Solution and then by checking Domain.
      using Domain.Repositories;
      namespace FilmsRUsOnline.Controllers
      {
      public class FilmsController : Controller
      {
      private IFilmsRepository filmsRepository;
      public FilmsController()
      {
      filmsRepository = new DummyFilmsRepository();
      }
      public ViewResult List()
      {
      return View(filmsRepository.Films);
      }
      }
      }

slide ASP.NET

    1. View code file.
    2. When the application starts it needs to run the the appropriate action method. For this, under App_Start in the Solution Explorer, ensure that RouteConfig.cs is set as the following.
      routes.MapRoute(
      name: "Default",
      url: "{controller}/{action}/{id}",
      defaults: new { controller = "Films", action = "List", id = UrlParameter.Optional }
      );
    3. View code file.
    4. We need to create a view so as to display film information; to do this we are going to take advantage of the layout pages in ASP.NET. A layout page contains standard content that can be incuded in multiple pages.
    5. To create a view, as previously shown in an earlier MVC tutorial, right click the action method in the FilmsController called List() and then select Add View.
    6. Click the check-box Create a strongly-typed view and use this as the Model Class IEnumerable and as the layout page using the dialog button select Views/Shared/_Layout.cshtml.

ViewLayoutandstrong

  1. For the view called Lists use this Razor implementation. This view is bound to a list of films whether this is from a dummy repository or an SQL database. The section starting @foreach will iterate through the list of bound films and will display their information starting with the title, then the blurb and finally the rental price.
    @model IEnumerable
    @{
    ViewBag.Title = "List of films";
    Layout = "~/Views/Shared/_Layout.cshtml";
    }
    @foreach(var film in Model) {
    <div class="item">
    <h4>@film.Title</h4>
    <p>Blurb: @film.Blurb</p>
    <p>Rental price: @film.RentalPrice.ToString("c")</p>
    </div>
    }
  2. View code file.
  3. Now we are able to run the application and the movies including their details should be displayed.

Lab 4: Interacting with a Database

Lab 4: Interacting with a Database

To enhance the application we are now going to use a “real repository” that connects to a database. The database is called FilmsRUs. Click here to download a script. Then unzip and run the script in SQL Server to create the database, including its data.
There are many ways to access the database; we are going to use the popular entity framework (EF) API.
There are also a few strategies available in using EF, we are going to use the code-first approach.
EntityFrame

  1. The first step is to install EF 5 in the domain project – see above.
    • In Solution Explorer, right click references and select NuGet Packages.
    • Select on-line in the left-hand tab section.
    • Then install Entity Framework.
  2. In entity framework you must define a data context class, this defines which entity sets are included in the data model. To allow us to do this we are going to use DbContext class which represents an individual unit of work
  3. Create a class that inherits from DbContext called FilmsRUsContext in the Repositories folder.
    using System.Data.Entity;
    using Domain.Entities;
    namespace Domain.Repositories
    {
    public class FilmsRUsContext : DbContext
    {
    public DbSet Films { get; set; }
    public FilmsRUsContext(string connectionString)
    : base(connectionString)
    {}
    }
    }
  4. View code file.
  5. Now we need to implement a real repository, this will connect to the FilmsRUs database and return data to the SqlFilmsRepository. This is held in the Repositories folder.
    using Domain.Entities;
    using System.Data.Entity;
    namespace Domain.Repositories
    {
    public class SqlFilmsRepository : IFilmsRepository
    {
    private DbSet films;
    public SqlFilmsRepository(string connectionString)
    {
    films = (new FilmsRUsContext(connectionString)).Films;
    }
    public IList Films
    {
    get { return films.ToList(); }
    }
    }
    }
  6. View code file.
  7. We now need to enhance FilmsController to use the real repository. This is done in the controller’s constructor.
    using Domain.Repositories;
    namespace FilmsRUsOnline.Controllers
    {
    public class FilmsController : Controller
    {
    private IFilmsRepository filmsRepository;
    public FilmsController()
    {
    string connStr = @"Server=.\SQLEXPRESS;Database=FilmsRUs;Trusted_Connection=yes;";
    filmsRepository = new SqlFilmsRepository(connStr);
    }
    public ViewResult List()
    {
    return View(filmsRepository.Films);
    }
    }
    }
  8. View code file.
  9. You can now run the application and check to see what films are displayed.

Lab 5: Using Dependency Injection

Lab 5: Using Dependency Injection

Dependency Injection (DI) enables you to decouple application components from each other. We can easily change or inject objects when we require them. Using DI makes applications much easier to test and maintain.

    1. Key principles of DI are:
      • Uses interfaces.
      • Define constructor(s) that can be supplied a dependency object.
      • Use a DI container tool to provide a suitable dependency object.
    2. We need to download a DI Container for .NET; for this we are going to use Ninject.
    3. Firstly Download from https://ninject.org/
      • Once Downloaded Unzip and put on your file system.
      • Right click FilmsRUsOnline and select add reference.
      • Choose Browse from the left column and then click the browse button to bring up the dialog.
      • Go to the place where you saved the folder and select the Ninject.ddl.

Ninject

    1. Our controller class needs a repository object; at the moment, our controller creates the repository manually.
    2. DI offers a better solution, we can define a “controller factory” class, this creates a controller object, supplies it with a suitable repository object.
    3. Create a folder called Plumbing in FilmsRUsOnline and add a new class called NinjectControllerFactory.
    4. Use this to create the Dependency between the FilmRepository and the SqlFilmsRepository.
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Web;
      using Domain.Repositories;
      using System.Configuration;
      using System.Web.Mvc;
      using System.Web.Routing;
      using Ninject;
      using Ninject.Modules;
      public class NinjectControllerFactory : DefaultControllerFactory
      {
      private IKernel kernel = new StandardKernel(new FilmsRUsServices());
      protected override IController GetControllerInstance(RequestContext context, Type controllerType)
      {
      if (controllerType == null) return null;
      return (IController)kernel.Get(controllerType);
      }
      private class FilmsRUsServices : NinjectModule
      {
      public override void Load()
      {
      string connStr = ConfigurationManager.ConnectionStrings["FilmsRUsDatabase"].ConnectionString;
      Bind<IFilmsRepository>()
      .To<SqlFilmsRepository>()
      .WithConstructorArgument("connectionString", connStr);
      }
      }
      }
    5. View code file.
    6. For this code to work make sure a connection string is defined in your web.config file.
      <add name="FilmsRUsDatabase"
      connectionString="Server=.\SQLEXPRESS;Database=FilmsRUs;Trusted_Connection=yes;"
      providerName="System.Data.SqlClient" />
    7. View code file.
    8. Now we must tell ASP.NET MVC to use our controller factory.

global2

  1. To use the custom controller factory
    • Open the Global.asax.cs file.In the ASP.NET MVC project.
    • Then modify Application_Start() event handler like so:
      using FilmsURsOnline.Plumbing;
      protected void Application_Start()
      {
      AreaRegistration.RegisterAllAreas();
      WebApiConfig.Register(GlobalConfiguration.Configuration);
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
      RouteConfig.RegisterRoutes(RouteTable.Routes);
      BundleConfig.RegisterBundles(BundleTable.Bundles);
      AuthConfig.RegisterAuth();
      // Tell ASP.NET MVC to use our controller factory.
      ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
      }
  2. View code file.
  3. Now we can re-factor the controller class to use dependency injection.
    public class FilmsController : Controller
    {
    private IFilmsRepository filmsRepository;
    public FilmsController(IFilmsRepository filmsRepository)
    {
    this.filmsRepository = filmsRepository;
    }
  4. View code file.
  5. You can now run the application. It displays the information from the database. Can you explain why?

Lab 6: Unit Testing the Application

Lab 6: Unit Testing the Application

One of the key benefits of ASP.NET MVC is that it facilitates easy unit testing. We can then apply Test Driven Development (TDD)- this means we define a test first to specify the outcome for a new behaviour. Then implement functionality so that the test is passed.
We are going to create a simple unit-test that checks to see if the views have been made and are accessible. A more in depth look into unit tests will be in a later tutorial in this course.

    1. Go to the project that we created at the start of the application called FilmsRUsOnline.Tests.
    2. Under the References make sure that both Domain and FilmRUsOnline assemblies are included.

Test

  1. In the Controllers folder open HomeControllerTest.cs and change as follows.
    using FilmsURsOnline;
    using FilmsURsOnline.Controllers;
    using Domain.Repositories;
    using Domain.Entities;
    [TestClass]
    public class HomeControllerTest
    {
    private IFilmsRepository filmsRepository;
    [TestMethod]
    public void Index()
    {
    // Arrange
    FilmsController controller = new FilmsController(filmsRepository);
    // Act
    ViewResult result = controller.Index() as ViewResult;
    // Assert
    Assert.IsNotNull(result);
    }
    [TestMethod]
    public void About()
    {
    // Arrange
    FilmsController controller = new FilmsController(filmsRepository);
    // Act
    ViewResult result = controller.Index() as ViewResult;
    // Assert
    Assert.IsNotNull(result);
    }
    [TestMethod]
    public void Contact()
    {
    // Arrange
    FilmsController controller = new FilmsController(filmsRepository);
    // Act
    ViewResult result = controller.Contact() as ViewResult;
    // Assert
    Assert.IsNotNull(result);
    }
    }
  2. View code file.
  3. The code above will check to make sure the views are not referring to a null reference; hence not been made.
  4. To run the tests select:
    • Test on the main navigation bar.
    • Then select Run.
    • Finally select All Tests.
  5. You will see that all three test have failed, this is because we need to add the action methods to the FilmController.
    [HttpGet]
    public ActionResult About()
    {
    return View();
    }
    [HttpGet]
    public ActionResult Contact()
    {
    return View();
    }
    [HttpGet]
    public ActionResult Index()
    {
    return View();
    }
  6. View code file.
  7. If you need to connect them with a view if it hasn’t done this already;
    • Right click the action method.
    • Add View.
    • Use the Layout pages found under the folder Films.
  8. You can now run the tests and will receive passes as the views have been made.
    Home
  9. As an extra in a later tutorial we are going to add a limit to the items on a page. This feature will be implemented using TDD
    public class FilmsController : Controller
    {
    private IFilmsRepository filmsRepository;
    public int PageSize = 3;
    public FilmsController(IFilmsRepository filmsRepository)
    {
    this.filmsRepository = filmsRepository;
    }
    public ViewResult List(int pageNumber = 1)
    {
    return View(filmsRepository.Films
    .Skip((pageNumber - 1) * PageSize)
    .Take(PageSize)
    .ToList());
    }
    }

We will explore TDD more in that later tutorial. We will add features but check the process as we go with unit tests.

 

Well done. You have completed the tutorial in the MVC4 course. The next tutorial is

3. ASP.NET MVC4 Test Driven Development


Back to beginning
Copyright © 2016 TalkIT®






If you liked this post, please comment with your suggestions to help others.
If you would like to see more content like this in the future, please fill-in our quick survey.
Scroll to Top