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:
-
In the CarRentWebSite project, right-click the Controllers folder, point Add and select Controller....
-
The Add Controller dialog appears. From the Template drop-down, select Controller with empty read/write actions.
-
Add two controllers named respectively CarController and CategoryController.
Each controller class will be created with ActionResult methods: Index, Details, Create, Edit and Delete.
-
Open the CategoryController class. Add the following using/Imports statements:
using SofiaCarRental.Model
Imports SofiaCarRental.Model
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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.