Exercise 2: Using Models in Razor Views

In this exercise, you will work with models in Razor views. Initially, you will use the @inherits directive that was released as part of MVC 3.0, and then the new @model directive that is now supported in the Razor engine. These directives provide a simplified way to reference your strongly-typed models in your view files. You will add view templates used by action methods to browse the albums in the music store.

Task 1 – Using the @inherits Directive

In this task, you will replace the Index action method of the HomeController to retrieve the Date & time formatted in the webserver’s culture.

  1. If not already open, start Microsoft Visual Web Developer 2010 Express from Start | All Programs | Microsoft Visual Studio 2010 Express | Microsoft Visual Web Developer 2010 Express.
  2. In the File menu, choose Open Project. In the Open Project dialog, browse to Source\Ex02-UsingModelsInRazorViews\Begin, select MvcMusicStore.sln and click Open.
  3. In the Solution Explorer, browse to the Controllers folders and then double-click the HomeController.[cs|vb] class.
  4. Replace the implementation of the view method, to pass the current Date and Time to the view. To do this, replace the following code.

    C#

    using System;
    FakePre-ce99fcd6c8f645ac80b9cc8e504ab89a-25e665c7cca2455bbf9b9b27c52928feFakePre-63bc6e3ecc554ee4a1154092c8be7055-47a371c51ce645b7874d9c39a13035d4FakePre-056afaaf003c4867ba84be05bb7a2933-7125e2cd1e0247ddbea09bed849ab1aeFakePre-869b1aecde9046fa9a138cb7b992acc8-ece9de7e8ef642079f8580e75da20a3dFakePre-b65850d28a8c441097cbd4d795d8f7ed-38dc4172efdb40b6919ea838ceaa87afFakePre-b70da183de05441bb50339be0cca618f-459a00264aaa4ba6ace6ba83b69f4857FakePre-57f11a5d95f643aca4f54418e8cb3b59-bd9c9d07834b44f5a49b2f33ac952f80FakePre-49f58381a8074dd6b471d4d8a174ac55-afa03e7f2dd144ce90347d779ecdfa65FakePre-effa29ca968a4908a0283bc151ce18f4-3223d9209dfc4b4fb8d7ff695cdaedb7FakePre-4c8ec5c524474e899bddbf7b9328de8d-bee38856d6ed419ba9d1339c0ba889fdFakePre-593fab972d644074bb0400e81dc240c0-c00ccf5f013b4b3e97ef7683b5e469b6FakePre-c964e111cbf847f082f1fda698164aa6-b529ba1aa9084db992289b0eee3720eeFakePre-d46b24db30344716942ea7481cb925c1-d297ba63cac944458c8d194e2ed212b3FakePre-367531af0aa34d06bdf041375b4188c8-b06bcdff93bf4e959d5ef7f9df8a60cb return View(DateTime.Now);FakePre-42586865bfed4f5eabc397a6dfc914e4-d5c57b31d2624496a7405f311080a67eFakePre-310a72dd000a4c12b968078ddcb878ca-77c72291b69c4ad0ba9cbe3e08bb648cFakePre-dc0f6d474d3043ef88cb3c8a85d6d58c-71f8cce135a04fb0af1bb61ea0d1c60fFakePre-776ecd9d2ac544caaef19a0a706cbd13-3ca2fa4492164097a5ab7739a054c7f5

    Visual Basic

    Imports System
    FakePre-c3508a261e864d2b8e3a8b818ef58d63-f371d62d5fd2438495d3a367688bc3b2FakePre-6498399e6a3b4a80802396b5fa1663d9-0c66633717e74132ad830dafb5d61857FakePre-a14c5aae2b164f608dc0834490f69cef-63f8d8866fe348fbb0442cf53cf24528FakePre-915de189aac14c4a9a30f28f0f15bef0-6ae8e1513f734910a2dc438a2264d6d9FakePre-65ebc942a8d546b49958ccd5026c3f38-4960fad02fdb4640891b5b125ac19c57FakePre-f5a1af9112844ad48142448aeeee3f06-0972dd59f88d48ec858e266fedb8cfd7FakePre-31794daef6ed4cbda7d009cf5e63008f-61effc48449d409c84b158a1fe900a98FakePre-76a30fb180b04ede855788b596751e6c-1e76af8168f0449b958e3eb2cce4b275FakePre-1a2d6f4f80494102b6b41b75c3cad431-facff6c1fb6b4f53b21c950a6057f485FakePre-9592145880cb45d9914da6f2fcc85a4c-4b6dec88cdbb44f09d201225225b7505FakePre-e5fd2f43e5ef4df9a345a6160dcb6e54-f970b3a0e4454900a850d8640b64234fFakePre-5cfb35a1fc174bf68b7ffa29638e7d73-6167e33c29ea4f14914efafa6aaf63a9FakePre-719b4f0d27e04e13a7b810848d3d6831-7424f729e2e740f1a26703cbd2fd40b8FakePre-a58941b43c6148b59edf9aa37a28cd9b-b5db39b3d37f43a2a21360b795cf3e18 return View(DateTime.Now)FakePre-a63b1df03dda41219115a0eb83d17d6f-135b05055358456f862647128cc42b45FakePre-db00644a14b94d9da5c908374d1eccd9-7e223692d9a24bfbb1e134503db42ca6FakePre-b1f3f4e5c889416682ffd95f67972bdd-52e313ee7c8143a28e896dcbccf35cfaFakePre-a8905b5108dd478897a628edf3bf1a00-e154afbc685e434aa7108965cc518f61

  5. Open the Index view associated to this controller. To do this in the Solution Explorer navigate to Views\Home and double-click Index.cshtml|vbhtml.
  6. Replace the @model dynamic; line at the top with the following one:

    C#

    @inherits System.Web.Mvc.WebViewPage<DateTime>

    Visual Basic

    @inherits System.Web.Mvc.WebViewPage(Of DateTime)

    Note:
    Note: The @inherits directive indicates that you want to derive the view from System.Web.Mvc.WebViewPage<DateTime> class. This way, you can define strong-type models inside a Razor’s view.

  7. Add a reference to the System.Globalization namespace bellow the @inherits directive. To do this, add the following line:

    cshtml

    @inherits System.Web.Mvc.WebViewPage<DateTime>
    FakePre-de57bf4f51e3437189c57b66c07dbebf-d6b4840570234da0be98cf52e11c7801@using System.Globalization;

    vbhtml

    @inherits System.Web.Mvc.WebViewPage(Of DateTime)
    FakePre-d068dc2baa074cb9a7094024e2614712-7e62235fe0bd4d3db4498004a737f9f1@Imports System.Globalization

  8. Replace the code block that informs the Date and Time with the following one.

    cshtml

    @{
    FakePre-b134e1d8def8402c977bfae0242576cc-8aa2a28e6a8c4306babb5cd65904cf93FakePre-404678d5b0ef403f9a3f97bcd3239767-1cc549294cb44b06ba5d544a6f6c1b5aFakePre-b322acbbcf7e483aac867553a808253b-36b1b56e7e114f53a73750fb83a82735FakePre-b4de824e4b9d408fb5dfba134623e061-7c9e7a6c3eea4d0fbf1911ed29d419f6 <text> Current time is @Model.ToString(CultureInfo.CurrentUICulture) </text>FakePre-f7597fb3d02248dcb6b4848d69eecf46-21074528d6a7426689b28eea217f9e89

    vbhtml

    @Code
    FakePre-28b4d723e6bc41e0861ef9c173f742a4-0c8da62ef60d43b9a653929c89c9f079FakePre-dd3f6b6e7fcd48ddaef38769eac13864-b55cbf3481814953a1707a51e1daa2b5FakePre-f0494693a51f496688b4852aede0a16a-8b37825025da44b2b4760d79f046cbd6FakePre-53b475f2bd874f1d8f92912fac779c47-dc2f9cdfebcc44139c590d2da76f0701 @<text> Current time is @Model.ToString(CultureInfo.CurrentUICulture) </text>FakePre-f9722c37f3bd42869db3d254d8e83b14-7ceced62f68e46c990dcf60968bbf15f

    Note:
    The @Model is replaced by the type passed to the view: DateTime.Now. Additionally, the ToString method is invoked with the CurrentUICulture to show the Culture configuration for the user interface.

Task 2 – Running the Application

  1. Press F5 to run the application.
  2. The project starts in the Home page. Verify that Razor view is loaded and the Date andTime is displayed:

    Figure 11

    Running the Home page

Task 3 – Adding a View Template in Razor

In this task, you will add a new Index.cshtml|vbhtml view, in this case, using the @model directive. This directive, represents an improvement for the @inherits, simplifying the use of strongly-typed model classes in the view. You simply write @model StrongModelTypeat the top of the cshtml file, replacing the @inherits directive. You will add a view template in Razor for the Store Index page, which shows a list of Genres. At the end of the task you should get the same functionality you had when using ASPX templates, but with a simplified code.

  1. Before creating the new View template, you should build the project so that the Add View Dialog knows about the ViewModel class to use. Build the project by selecting the Debug menu item and then Build MvcMusicStore.

    Figure 12

    Building the project in Visual Web Developer 2010

  2. Open the StoreController.[cs|vb] file and right-click inside the Index Action method to display the context menu. Select Add View menu option to display the dialog box.

    Figure 13

    Adding a View from the Action method – C#

    Figure 14

    Adding a View from the Action method - VB

  3. The Add View dialog appears. Fill the dialog box according to the following values:
    1. Check “Create a strongly-typed view”.
    2. Choose “StoreIndexViewModel (MvcMusicStore.ViewModels)” at Model class.
    3. Check “Use a layout or master page” and verify that Razor Layout template path is “~/Views/Shared/Site.cshtml|vbhtml” by clicking the “” button and then click Add.

      Figure 15

      Adding a new Razor View dialog box – C#

      Figure 16

      Adding a new Razor View dialog box – VB

  4. Visual Studio generates an Index.cshtml|vbhtml Razor view template inside the Views\Store folder with the following structure:

    cshtml

    @model MvcMusicStore.ViewModels.StoreIndexViewModel @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/Site.cshtml"; } <h2>Index</h2>

    vbhtml

    @modeltype MvcMusicStore.ViewModels.StoreIndexViewModel @Code ViewBag.Title = "Index" Layout = "~/Views/Shared/Site.vbhtml" End Code <h2>Index</h2>

    Note:
    The @model StrongModelType directive at the top of the View specifies its base class. By default Razor will make the view to derive from System.Web.Mvc.WebViewPage<TModel>.

    Inside the @{ } block , the view sets the layout that will be used, and also sets the value for the ViewBag.Title element.

  5. Add logic in the Index .cshtml|vbhtml to show the list of genres from the model. To do this, replace the content of the generated file with the following one:

    cshtml

    @model MvcMusicStore.ViewModels.StoreIndexViewModel
    FakePre-b827ad14b03e40b3a4a1d7e89bc7f9b4-e2e5ffabb97145cb8c9305f19ed57849@{ ViewBag.Title = "Browse Genres"; Layout = "~/Views/Shared/Site.cshtml"; } <h2>Browse Genres</h2> <p>Select from @Model.NumberOfGenres</p> @foreach (string genreName in Model.Genres) { <li> @Html.ActionLink(genreName, "Browse", new { genre = genreName }, null) </li> }FakePre-a1e98a4f2045460f8b0ee204f53c3a4b-5c670471074c46018936fc84f3b4fe06FakePre-60e9ca56841c41d0a4c1b9b739158105-d25bd11a3524496faff5b1f93849d51dFakePre-b84ccf27e0b64954a40ff22dcc160c96-77cf865b448249c594c729abe595c30a

    vbhtml

    @model MvcMusicStore.ViewModels.StoreIndexViewModel
    FakePre-42bd5f9e51164bffbd96240d8f6e4771-86cd25f15d644286a5623efa1cb5f385@Code ViewBag.Title = "Browse Genres" Layout = "~/Views/Shared/Site.vbhtml" End Code <h2>Browse Genres</h2> <p>Select from @Model.NumberOfGenres</p> @For Each genreName in Model.Genres @<li> @Html.ActionLink(genreName, "Browse", New With{Key.genre = genreName }, null) </li> Next genreNameFakePre-c04193d999924fddbc02ef7008e323dc-a5c6f63ea94649f49e6d87f87324581aFakePre-610f183295bb419593ce46ea2a690281-5ff8219d59f442a7a173e81b811ecc64FakePre-50e99bc6cbc04ef098dc7fb0896cca3f-95557db7ac5f4bcaa44c8c772cdafe97

    Note:
    The foreach loops through the genres and generates an ActionLink to the Browse action method. This method is implemented in the provided solution, but its view will be created in task 5.

Task 4 – Running the Application

  1. Press F5 to run the application.
  2. The project starts in the Home page. Change the URL to /Store to verify that Razor view is loaded:

    Figure 17

    Browsing genres with a Razor View

Task 5 – Creating Browse CSHTML View and Adding Details CSHTML View

  1. In the previous task, you have learned how to add a Razor view. Now you will include the views that are missing from the original Music Store Application: Browse and Details.
  2. The cshtml files are included in the Source\Assets\cshtml folder of this Lab. In order to add them to the application, drag them from a Windows Explorer window into the Solution Explorer in Visual Web Developer Express, as shown below:

    Figure 18

    Dragging views – C#

    Figure 19

    Dragging views - VB

  3. Visual Studio will add Browse.cshtml|vbhtml and Details.cshtml|vbhtml Razor views.

    cshtml – Browse.cshtml

    @model MvcMusicStore.ViewModels.StoreBrowseViewModel @{ ViewBag.Title = "Browse Albums"; Layout = "~/Views/Shared/Site.cshtml"; } <h2>Browsing Genre: @Model.Genre.Name</h2> <ul> @foreach (var album in Model.Albums) { <li>@album.Title</li> } </ul>

    vbhtml – Browse.vbhtml

    @modeltype MvcMusicStore.ViewModels.StoreBrowseViewModel @Code ViewBag.Title = "Browse Albums" Layout = "~/Views/Shared/Site.vbhtml" End Code @<h2>Browsing Genre: @Model.Genre.Name</h2> <ul> @For Each album in Model.Albums @<li>@album.Title</li> Next album </ul>

    Note:
    The Browse.cshtml|vbhtml page will loop all the albums for the selected genre, listing their titles.

    cshtml – Details.cshtml

    @model MvcMusicStore.Models.Album @{ ViewBag.Title = "Details"; Layout = "~/Views/Shared/Site.cshtml"; } <h2>Album: @Model.Title </h2>

    vbhtml – Details.vbhtml

    @modeltype MvcMusicStore.Models.Album @Code ViewBag.Title = "Details" Layout = "~/Views/Shared/Site.vbhtml" End Code <h2>Album: @Model.Title </h2>

    Note:
    The Details.cshtml|vbhtml page displays the album title.

Task 6 – Running the Application

In this task, you will run the application to verify that Razor views are displayed as expected.

  1. Press F5 to run the application.
  2. The project starts in the Home page. Change the URL to /Store and click on Rock genre to verify that Details view can be loaded, with the same appearance as the .aspx pages:

    Figure 20

    Browsing genres albums with Razor View

  3. Change the URL to /Store/Details/5 to verify an album’s information.

    Figure 21

    Browsing album details with Razor View

Next Step

Exercise 3: Creating and Consuming Razor Helpers