14 Days Free Technical Video Training from WintellectNOW

  

Introducing MVC Development w/the Razor View Engine for Visual Studio Developers

Tags: ASP.NET, ASP.NET MVC, Razor, Visual Studio, Visual Studio 2010

The Razor View Engine is a precise, useful, light language that enables you to create views for MVC projects in ASP.NET still while keeping a separation of concerns, ability to test, and pattern based development.  ASP.NET MVC developers looking for a more concise syntax now have another option that's built-in (of course, there are many 3rd party view engines out there) with the language being a familiar light version of C#. 

The Razor View engine is used to create WebMatrix sites or Visual Studio MVC applications.  When using ASP.NET MVC with either engine, you'll stick to a style of development called "convention over configuration", meaning that you'll use certain naming conventions to name files, models, views, controllers, and other key application elements rather than storing lots of metadata about these same elements in a configuration file.  When using MVC in Visual Studio 2010, it's is setup so that you'll be guided to use convention over configuration, which becomes evident when exploring an ASP.NET MVC project.

Getting Started

Before you start, go and download these two things (as of this post; things are subject to change - these could end up in VS at some point):

You can also find the Razor Syntax Highlighter by choosing Extensions Manager from the Visual Studio Tools menu.  Once installed, MVC 3 project templates are available from Visual Studio.  The MVC 3 Web Application template allows you to use either the Web Forms View Engine or the Razor View Engine, while MVC 2 Applications contain only the WF View Engine.

image

When creating a new MVC 3 project a new dialog box appears asking which application type, view engine, and testing framework you'd like to use.  You can and should add a test project so you can test your code, then actually write some tests in it.   The image below demonstrates selecting the internet application project template using Razor as the view engine, as well as the test framework.  The internet application MVC template adds in ASP.NET membership & security features to the project by creating the necessary model, view and controller for logging on and registering as a site user.

image

Verify that the project is created with three folders, one each for Models, Views, and Controllers which is the same folder structure as a MVC 2 site.  The project also contains auxiliary folders and files needed for the application such as the Content & App_Data folders.   Since this is an MVC application using the Razor View Engine, you will see a different file extension - .cshtml.  The .cshtml files are Razor View Pages written using the Razor View Engine.  If you're not familiar with Razor syntax, I've blogged about it here, and the online documentation has more information as well. 

image  

The application template sets up some models, views and controllers to start with, and is now ready for new models, views, and controllers.  I've found the easiest way to work with MVC in VS is to start with the model, move to the controller, then create the view, so we'll look at models first.

Models

A model is a representation of an underlying data store.  Models can be almost anything from any data source; EF or Linq2Sql Models, or a simple class.  The code the builds the model below consists of two classes, a ProductModel class and a Product class.  The ProductModel class returns a List<t> of Product objects in a property aptly named Products that represents one or more products in the data store .  Product objects contain ProductNumber, Name and Price properties and represent an individual product in the data store.  The model code representing these product objects is below:

using System.Collections.Generic;
namespace AdventureWorks.Models
{
    public class ProductModel
    {
        public List<Product> Products { get; set; }
        public ProductModel()
        {
            Products = new List<Product>();
            this.Products.Add(new Product("AB-00-J1" ,"Super Fast Bike" ,1000M));
            this.Products.Add(new Product("EE-9-OL"  ,"Durable Helmet"  ,123.45M));
            this.Products.Add(new Product("MMM99-54" ,"Soft Bike Seat"  ,34.99M));
        }
    }

    public class Product
    {
        public Product(string productNumber, string name, decimal price)
        {
            Name = name;
            Price = price;       
            ProductNumber=productNumber;
        }
        public string ProductNumber { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
       
    }
}

Models are handed over to views by controllers so the views can render the data from the model.  The model will extend business logic (of course, this is a simple example, business logic will likely be spread out into other applications & tiers). Models also provide validation information to the view via metadata & code.  You can add the model to the \Models folder or you can reference an external data model library.  In this case, the model's been added to the \Models folder.

Controllers

Controllers are objects that inherit from the System.Web.Mvc.Controller class that match models with views.  During incoming requests, MVC's routing system kicks in and determines which controller method to use based on routing code set in the global.asax.cs file.  A default route is set in the global.asax.cs file that works for most of the routes you'll need, however, if need be then you can modify/add/delete your own routes.

Staying within convention, controller code files should go in the \Controllers folder. The controller class must follow the naming convention of YourNameController, i.e., ProductsController.  The controller's Index method, again following convention, must be named the same name as its view but without the file extension.  By following this pattern, the controller can have multiple actions that deliver data to multiple views, making code easier to write, maintain, and test.

namespace AdventureWorks.Controllers
{
    public class ProductsController : Controller
    {
        public ActionResult Index()
        {
            ProductModel p = new ProductModel();           
            return View(p.Products);
        }
    }
}

By observing the previous code sample and the conventions that it follows, it's clear that the Index method maps to the \Views\Products\Index.cshtml view.  The Index() method's return type is an ActionResult from the System.Web.Mvc namespace.  There's many different results that you can use for different scenarios such as ContentResult, FileResult, RedirectResult, ViewResult and others depending on your view's needs

Views

Views are a mechanism to format and render data in a browser from the model, as specified by the @model attribute (or @inherits) at the top of the view.  Views in ASP.NET MVC with either the ASPX or Razor View engines use a code-based way to render the page rather than relying on declarative controls, which create tight coupling and are hard to test.  Using the MVC approach creates cleaner output in the browser as well as cleaner and more terse syntax in the views as well.  Views are meant to only render the markup, code and data; they're not meant as a place to store business logic. The model and tiers accessed by the model, are the appropriate places to host business logic.  The view can have a small amount of UI validation logic,as a first line of defense for input sanitation, e.g., required, regex and range validators.

To add a view to your project, right click on the controller and select Add View. 

image

Visual Studio will need some information about the view, which is supplied in the Add View dialog box:

  1. Specify whether you want a strongly-typed view or not.  Creating a strongly-typed view allows you to refer to the underlying data structures in the classic object.property syntax.
  2. Specify the view data class.  The dropdown list displays classes in your project that are part of the data model.
  3. Specify the view engine.  ASPX and Razor are the options.
  4. Specify the view content.  Choices are list, details, edit. etc...  Choosing this option creates .cshtml or .aspx view pages that do page rendering for you.

image

Here's what choosing these options will produce in a Razor view page named \Views\Products\Index.cshtml:

@model List<AdventureWorks.Models.Product>
@{

View.Title = "Index";
Layout =
"~/Views/Shared/_Layout.cshtml"
;
}


<h2>Index</h2>
<
p>
@Html.ActionLink("Create New", "Create")
</p
>
<
table>
<tr>
<th>Edit/Details/Del</th>
<th>Product Number</th>
<th>Name</th>
<th>Price</th>
</tr>

@foreach (var item in
Model) {
<tr>
<td>
@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
<td>
@item.ProductNumber
</td>
<td>
@item.Name
</td>
<td>
@String.Format("{0:F}", item.Price)
</td>
</tr>
}
</table>

Since the view is strongly typed, the data structure can be accessed as it is - an object with properties.  The code above loops through the model and renders a <TR> for each entity that the model holds along with <TD> tags and the actual data in them (ProductNumber, name and Price).  The result is a simple list of the three products in model with accompanying action links.

image

The HTML source shows a clean, precise table rendered to the browser.

image

Summary

Rendering a list of products is very easy using MVC and the Razor View Engine, as is updating/manipulating the data (logically what you'd do next if following this example).   If you're digging deeper into learning MVC w/Razor the next topics you'll want to get into are jQuery and HTML validation helpers for client side validation, and decorating the model with data annotations (also for validation).  The MVC web site has a ton of great examples and tutorials.

Although many ASP.NET MVC samples use the ASPX/Web Forms view engine they're easily compared & converted to razor pages - so don't avoid them, it's still a great way to learn both MVC w/Razor and the ASPX engine.

8 Comments

  • Kapil Sharma said

    Very nice example. I would really appreciate, if you can post the Edit/Delete functionality using Razor.

    Thanks,
    Kapil

  • Kapil Sharma said

    Adding check for if model null, before binding will be good if binding from model. What do u say ?

    @if (Model != null)
    {

    }

  • Rachel said

    Kapil,

    Yes, will be posting some of the edit/del/ins with Razor in upcoming posts.

    Checking for nulls - you can't go wrong doing that so yes, a good idea.

  • Rachel said

    Tom,

    Oh no! It looks like it's gone from the code gallery.

    If you have SP1 you should get the same syntax highlighting. It's also available with the MVC 3 Tools update. There might be an extension or NuGet package available as well - will post it if I see anything.

Comments have been disabled for this content.