Bookmark and Share

First Look at the Razor CSharp HTML File in MVC 3

The day before I left for IEEE ICCSIT 2010, there was a huge announcement about a new view engine for ASP.NET: Razor. It was old news by the time I returned, but I couldn’t help but sit down and play with it. I skimmed a few a blog postings on it, but I wasn’t getting anything good. So, I downloaded the ASP.NET MVC 3 Preview 1 and began playing with it myself.

After installing the preview, I created a new ASP.NET MVC 3 Razor application. I then proceeded to open the Views/Home/Index.cshtml to see what it created for me.

@inherits System.Web.Mvc.WebViewPage

@{
    View.Title = "Home Page";
    LayoutPage = "~/Views/Shared/_Layout.cshtml";
}

<h2>@View.Message</h2>
<p>
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" 
title="ASP.NET MVC Website">http://asp.net/mvc</a>. </p>

The one thing I did pick up from skimming the blogs was that the @ symbol is the directive to replace all the <% %> symbols. From that, a few things become clear. The compiled class must not have a name, but it inherits from System.Web.Mvc.WebViewPage. Placing @ in front of curly braces enters a block, just like in regular code. WebViewPage has a View property and a LayoutPage property (which I assume replaces the MasterPage concept). And finally, accessing a variable in the middle of HTML works exactly like you’d expect.

The View.Title is a little fishy to me. WebViewPage does not define a generic class for the Model, and I don’t see any signs of the ViewData. I’m going to go out on a limb here and guess it's an ExpandoObject. Let’s open up WebViewPage with reflector and find out.

public dynamic View
{
    get
    {
        Func<ViewDataDictionary> viewDataThunk = null;
        if (this._dynamicViewData == null)
        {
            if (viewDataThunk == null)
            {
                viewDataThunk = () => this.ViewData;
            }
            this._dynamicViewData = new DynamicViewDataDictionary(viewDataThunk);
        }
        return this._dynamicViewData;
    }
}

Well, it’s not exactly an ExpandoObject, but it is dynamic. Instead of sticking values in itself, it’s sticking values in the ViewData dictionary. This means you can treat it like an ExpandoObject. I wrote View.Duck = “Quack”; on the line after View.Title, then I put <h3>@View.Duck</h3> at the bottom of the page. It worked like a charm.

The layout page contains what one would expect from a layout page. It contains the primary html that embodies the site including the head, the body, the menu, and the footer. The primary thing here is that it renders the body of the view by calling @RenderBody().

<div id="main">
    @RenderBody()
    <div id="footer">
    </div>
</div>

The standard calls to the Html helper methods are in place, so there isn’t much to learn there.

<div id="logindisplay">
    @Html.Partial("_LogOnPartial")
</div>

<div id="menucontainer">

    <ul id="menu">
        <li>@Html.ActionLink("Home", "Index", "Home")</li>
        <li>@Html.ActionLink("About", "About", "Home")</li>
    </ul>

</div>

I know this could become more complicated when switching contexts from C# to HTML. However, if you’ve written complicated views with the aspx engine, it can already be messy. I’m confident from what I’ve seen so far that Razor cleans it up tremendously. What I find intriguing is the ASP.NET MVC team is starting to innovate with the .NET 4 language features. I can’t wait to dig deeper to see what they’ve done.

blog comments powered by Disqus

KodefuGuru.GetInfo()

Chris Eargle
LinkedIn Twitter Technorati Facebook

Chris Eargle
Telerik Developer Evangelist, C# MVP

JustCode

Telerik .NET Ninja

 

INETA Community Speakers Program

 

MVP - Visual C#

 

Friend of RedGate

World Map

Tag cloud

Month List

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.