Data Access has been discontinued. Please refer to this page for more information.

Creating the Controllers

The "C" in MVC stands for controller. The controller gathers up data and sends it to a view and responds to requests from the view. In this topic, you will implement the second part of the MVC pattern, i.e. the controllers.

To Create the Controllers:

  1. In the CarRentWebSite project, right-click the Controllers folder, point Add and select Controller....

  2. The Add Controller dialog appears. From the Template drop-down, select Controller with empty read/write actions.

  3. Add two controllers named respectively CarController and CategoryController.

  4. Each controller class will be created with ActionResult methods: Index, Details, Create, Edit and Delete.

  5. Open the CategoryController class. Add the following using/Imports statements:

    using SofiaCarRental.Model
    
    Imports SofiaCarRental.Model
    
  6. You need to define an FluentModel field in the CategoryController. The context will be initialized in the Initialize method:

    private FluentModel dbContext;
    
    protected override void Initialize(System.Web.Routing.RequestContext requestContext)
    {
       base.Initialize(requestContext);
       this.dbContext = ContextFactory.GetContextPerRequest();
    }
    
    Private dbContext As FluentModel
    
    Protected Overrides Sub Initialize(ByVal requestContext _
        As System.Web.Routing.RequestContext)
        MyBase.Initialize(requestContext)
        Me.dbContext = ContextFactory.GetContextPerRequest()
    End Sub
    
  7. The job of the Index method will be to return a list of Categories to be displayed in a view. By default an empty view is displayed.

    public ActionResult Index()
    {
       return View(this.dbContext.Categories.ToList());
    }
    
    Function Index() As ActionResult
     Return View(Me.dbContext.Categories.ToList())
    End Function
    
  8. The purpose of the Details method will be to return information for the current Category.

    public ActionResult Details(int id)
    {
        return View(this.dbContext.Categories.
            FirstOrDefault(category => category.CategoryID == id));
    }
    
    Function Details(ByVal id As Integer) As ActionResult
        Return View(Me.dbContext.Categories.
            FirstOrDefault(Function(category) category.CategoryID = id))
    End Function
    
  9. The next step is to add controller logic for creating new categories. The first Create method returns an empty View. You don't need to modify it (for now). The second Create method is the one that will be called when the view posts back. By default, the template told the second Create method to expect a FormCollection as a parameter. Because the Create view will be created as a strongly-typed view, it will be able to pass back a strongly typed Category object. Change the declaration of the second Create method to accept a Category object instead of a FormCollection. Next, modify the Create method so that it saves the new Category object to the database. In that method you are taking the new Category object and pass it to the OpenAccessContext. Then, the SaveChanges method is called.

    public ActionResult Create()
    {
       return View();
    }
    
    [HttpPost]
    public ActionResult Create(Category newCategory)
    {
       try
       {
           this.dbContext.Add(newCategory);
           this.dbContext.SaveChanges();
           return RedirectToAction("Index");
       }
       catch
       {
           return View();
       }
    }
    
    Function Create() As ActionResult
     Return View()
    End Function
    
    <HttpPost()> _
    Function Create(ByVal newCategory As Category) As ActionResult
     Try
      Me.dbContext.Add(newCategory)
      Me.dbContext.SaveChanges()
      Return RedirectToAction("Index")
     Catch
      Return View()
     End Try
    End Function
    
  10. The next method you are going to implement is the Edit method. When the user edits a category, you will first need to retrieve that category from the database and then send it to the Edit view. By default, the template told the second Edit method to expect a FormCollection as a parameter. However, the Edit view will be created as a strongly-typed view. That's why it will be able to pass back a strongly typed Category object. Change the declaration of the second Edit method to accept a Category object instead of a FormCollection The purpose of the "postback" Edit method is to update the Category in the database with the new data that came from the view. The logic is pretty simple. You need to load the original Category object from the database and modify it with the new values. After that, you need to call the SaveChanges method.

    public ActionResult Edit( int id )
    {
        return View(this.dbContext.Categories.
            FirstOrDefault(category => category.CategoryID == id));
    }
    
    [HttpPost]
    public ActionResult Edit(int id, Category categoryToUpdate)
    {
        try
        {
            // 1. Load the original category from the database.
            Category originalCategory = this.dbContext.Categories.
                FirstOrDefault( category => category.CategoryID == id );
    
            // 2. Update with the new data.
            originalCategory.CategoryName = categoryToUpdate.CategoryName;
            originalCategory.ImageFileName = categoryToUpdate.ImageFileName;
    
            // 3. Save changes.
            this.dbContext.SaveChanges();
    
            return RedirectToAction( "Index" );
        }
        catch
        {
            return View();
        }
    }
    
    Function Edit(ByVal id As Integer) As ActionResult
        Return View(Me.dbContext.Categories.
            FirstOrDefault(Function(category) category.CategoryID = id))
    End Function
    
    <HttpPost()> _
    Function Edit(ByVal id As Integer, ByVal categoryToUpdate As Category) As ActionResult
        Try
            ' 1. Load the original category from the database.
            Dim originalCategory As Category =
            Me.dbContext.Categories.FirstOrDefault(Function(category) category.CategoryID = id)
    
            ' 2. Update with the new data.
            originalCategory.CategoryName = categoryToUpdate.CategoryName
            originalCategory.ImageFileName = categoryToUpdate.ImageFileName
    
            ' 3. Save changes.
            Me.dbContext.SaveChanges()
    
            Return RedirectToAction("Index")
        Catch
            Return View()
        End Try
    End Function
    
  11. Deleting a Category will work analogically. The first Delete method is absolutely the same as the corresponding Edit method. And the postback Delete method is similar. First, you need to retrieve the original category from the database and then delete it.

    public ActionResult Delete( int id )
    {
        return View(this.dbContext.Categories.
            FirstOrDefault(category => category.CategoryID == id));
    }
    
    [HttpPost]
    public ActionResult Delete( int id, FormCollection collection )
    {
        try
        {
            // 1. Load original category from the database.
            Category categoryToDelete = this.dbContext.Categories.
                FirstOrDefault(category => category.CategoryID == id);
    
            // 2. Pass it to the Delete method.
            this.dbContext.Delete( categoryToDelete );
    
            // 3. Save changes.
            this.dbContext.SaveChanges();
    
            return RedirectToAction( "Index" );
        }
        catch
        {
            return View();
        }
    }
    
    Function Delete(ByVal id As Integer) As ActionResult
        Return View(Me.dbContext.Categories.
            FirstOrDefault(Function(category) category.CategoryID = id))
    End Function
    
    <HttpPost()> _
    Function Delete(ByVal id As Integer, ByVal collection As FormCollection) As ActionResult
        Try
            ' 1. Load original category from the database.
            Dim categoryToDelete As Category =
            Me.dbContext.Categories.FirstOrDefault(Function(category) category.CategoryID = id)
    
            ' 2. Pass it to the Delete method.
            Me.dbContext.Delete(categoryToDelete)
    
            ' 3. Save changes.
            Me.dbContext.SaveChanges()
    
            Return RedirectToAction("Index")
        Catch
            Return View()
        End Try
    End Function
    
  12. At this point you will implement the logic necessary for the proper disposal of OpenAccessContext.

    protected override void Dispose(bool disposing)
    {
        ContextFactory.Dispose();
        base.Dispose(disposing);
    }
    
    Protected Overrides Sub Dispose(disposing As Boolean)
        ContextFactory.Dispose()
        MyBase.Dispose(disposing)
    End Sub
    
  13. The implementation of the CarController is absolutely the same. The code for the CarController is listed below.

    using System.Linq;
    using System.Web.Mvc;
    using SofiaCarRental.Model;
    
    namespace CarRentWebSite.Controllers
    {
        public class CarController : Controller
        {
            private FluentModel dbContext;
    
            protected override void 
                Initialize(System.Web.Routing.RequestContext requestContext)
            {
               base.Initialize( requestContext );
               this.dbContext = ContextFactory.GetContextPerRequest();
            }
    
            public ActionResult Index()
            {
               return View(this.dbContext.Cars.ToList());
            }
    
            public ActionResult Details( int id )
            {
               return View(dbContext.Cars.FirstOrDefault(c => c.CarID == id));
            }
    
            public ActionResult Create()
            {
               return View();
            }
    
            [HttpPost]
            public ActionResult Create(Car newCar)
            {
               try
               {
                   this.dbContext.Add(newCar);
                   this.dbContext.SaveChanges();
    
                   return RedirectToAction("Index");
               }
               catch
               {
                   return View();
               }
            }
    
            public ActionResult Edit( int id )
            {
               return View(this.dbContext.Cars.FirstOrDefault(c => c.CarID == id));
            }
    
            [HttpPost]
            public ActionResult Edit(int id, Car carToUpdate)
            {
               try
               {
                   Car originalCar = dbContext.Cars.FirstOrDefault( c => c.CarID == id );
                   originalCar.ABS = carToUpdate.ABS;
                   originalCar.AirConditioner = carToUpdate.AirConditioner;
                   originalCar.ASR = carToUpdate.ASR;
                   originalCar.Available = carToUpdate.Available;
                   originalCar.CarYear = carToUpdate.CarYear;
                   originalCar.DVDPlayer = carToUpdate.DVDPlayer;
                   originalCar.Latitude = carToUpdate.Latitude;
                   originalCar.Longitude = carToUpdate.Longitude;
                   originalCar.ImageFileName = carToUpdate.ImageFileName;
                   originalCar.Make = carToUpdate.Make;
                   originalCar.Model = carToUpdate.Model;
                   originalCar.Mp3Player = carToUpdate.Mp3Player;
                   originalCar.Navigation = carToUpdate.Navigation;
                   originalCar.NumberOfRatings = carToUpdate.NumberOfRatings;
                   originalCar.Rating = carToUpdate.Rating;
                   originalCar.TagNumber = carToUpdate.TagNumber;
    
                   dbContext.SaveChanges();
    
                   return RedirectToAction("Index");
               }
               catch
               {
                   return View();
               }
            }
    
            public ActionResult Delete(int id)
            {
               return View(this.dbContext.Cars.FirstOrDefault(c => c.CarID == id));
            }
    
            [HttpPost]
            public ActionResult Delete(int id, FormCollection collection)
            {
               try
               {
                   Car car = this.dbContext.Cars.FirstOrDefault(c => c.CarID == id);
                   dbContext.Delete(car);
    
                   dbContext.SaveChanges();
    
                   return RedirectToAction("Index");
               }
               catch
               {
                   return View();
               }
            }
            protected override void Dispose(bool disposing)
            {
                ContextFactory.Dispose();
                base.Dispose(disposing);
            }
        }
    }
    
    Imports CarRentWebSite.OpenAccess
    
    Public Class CarController
        Inherits System.Web.Mvc.Controller
    
        Private dbContext As FluentModel
    
        Protected Overrides Sub Initialize(ByVal requestContext As System.Web.Routing.RequestContext)
            MyBase.Initialize(requestContext)
    
            Me.dbContext = ContextFactory.GetContextPerRequest()
        End Sub
    
        Function Index() As ActionResult
            Return View(Me.dbContext.Cars.ToList())
        End Function
    
        Function Details(ByVal id As Integer) As ActionResult
            Return View(Me.dbContext.Cars.FirstOrDefault(Function(car) car.CarID = id))
        End Function
    
        Function Create() As ActionResult
            Return View()
        End Function
    
        <HttpPost()> _
        Function Create(ByVal newCar As Car) As ActionResult
            Try
                Me.dbContext.Add(newCar)
                Me.dbContext.SaveChanges()
    
                Return RedirectToAction("Index")
            Catch
                Return View()
            End Try
        End Function
    
        Function Edit(ByVal id As Integer) As ActionResult
            Return View(Me.dbContext.Cars.FirstOrDefault(Function(car) car.CarID = id))
        End Function
    
        <HttpPost()> _
        Public Function Edit(ByVal id As Integer, ByVal carToUpdate As Car) As ActionResult
            Try
                Dim originalCar As Car = dbContext.Cars.
                    FirstOrDefault(Function(c) c.CarID = id)
    
                originalCar.ABS = carToUpdate.ABS
                originalCar.AirConditioner = carToUpdate.AirConditioner
                originalCar.ASR = carToUpdate.ASR
                originalCar.Available = carToUpdate.Available
                originalCar.CarYear = carToUpdate.CarYear
                originalCar.DVDPlayer = carToUpdate.DVDPlayer
                originalCar.Latitude = carToUpdate.Latitude
                originalCar.Longitude = carToUpdate.Longitude
                originalCar.ImageFileName = carToUpdate.ImageFileName
                originalCar.Make = carToUpdate.Make
                originalCar.Model = carToUpdate.Model
                originalCar.Mp3Player = carToUpdate.Mp3Player
                originalCar.Navigation = carToUpdate.Navigation
                originalCar.NumberOfRatings = carToUpdate.NumberOfRatings
                originalCar.Rating = carToUpdate.Rating
                originalCar.TagNumber = carToUpdate.TagNumber
    
                dbContext.SaveChanges()
    
                Return RedirectToAction("Index")
            Catch
                Return View()
            End Try
        End Function
    
        Function Delete(ByVal id As Integer) As ActionResult
            Return View(Me.dbContext.Cars.FirstOrDefault(Function(car) car.CarID = id))
        End Function
    
        <HttpPost()> _
        Function Delete(ByVal id As Integer, ByVal collection As FormCollection) As ActionResult
            Try
                ' 1. Load original car from the database.
                Dim carToDelete As Car = Me.dbContext.Cars.FirstOrDefault(Function(car) car.CarID = id)
    
                ' 2. Pass it to the Delete method.
                Me.dbContext.Delete(carToDelete)
    
                ' 3. Save changes.
                Me.dbContext.SaveChanges()
    
                Return RedirectToAction("Index")
            Catch
                Return View()
            End Try
        End Function
    
        Protected Overrides Sub Dispose(disposing As Boolean)
            ContextFactory.Dispose()
            MyBase.Dispose(disposing)
        End Sub
    End Class
    

In this topic, you implemented the second part of the MVC pattern, i.e. the Controller. The next step is to create the views.