Catch me next week at TechEd Eilat

Next week I’ll be around at TechEd Eilat and I’m looking forward to meet, talk, discuss, drink, eat and p-a-r-t-y with you people. So catch me, I’ll be the guy with the laptop :-P

And thanks Microsoft for choosing me to be their guest!

 

See you there,
Shay.




The Big View Engine Comparison – Razor vs. Spark vs. NHaml vs. Web Forms View Engine

One of the cool things about ASP.NET MVC (and other MVC web frameworks) is its capability to change the default view engine with a Microsoft or a 3rd-party one. ASP.NET MVC currently has a few options for view engine alternatives:

  • The web forms view engine – this view engine, with the ASP-like syntax, is the default one for ASP.NET MVC 1 and 2 applications.
  • Razor – the new view engine which will be the default one for ASP.NET MVC 3 applications.
  • Spark – an open-source view engine which aims to seamlessly integrate code and HTML.
  • NHaml – a port of the Ruby on Rails successful view engine named Haml. This open-source view engine aims to replace HTML tags with an easier to read and better organized syntax.

Note: Spark and NHaml are currently available for ASP.NET MVC 2. NHaml also doesn’t support .NET 4 at the moment. I believe that they will become available for version 3 as soon as it is out (moreover, they are open-source so you can help getting there!). Razor, on the other end, is not available on ASP.NET MVC 2 and below.

In this post I’ll go through the basic operations we do with our views and show you how to get them done with the different view engines mentioned above.

Displaying Variable Content

Here I’m comparing the way to present the content of ViewData["Message"] as an html-encoded string.

The Web Forms View Engine

<%: ViewData["Message"] %>

Razor

@ViewData["Message"]

Spark

${ViewData["Message"]}

 

NHaml

&= ViewData["Message"]

 

Conditions

Here I’m comparing the way of writing an if condition to display “<p>Party</p>” between 6AM and 9PM and “<p>It’s bed time</p>” between 9PM and 6AM.

The Web Forms View Engine

<% if (DateTime.Now.Hour > 20 || DateTime.Now.Hour < 6)
   { %>
  <p>It's bed time!</p>
<% } else { %>
  <p>Party!</p>
<% } %>

 

Razor

@if (DateTime.Now.Hour > 20 || DateTime.Now.Hour < 6) {   
  <p>It's bed time!</p>
} else {
  <p>Party!</p>
}

 

Spark

<if condition='DateTime.Now.Hour > 20 || DateTime.Now.Hour < 6'>
  <p>It's bed time!</p>
</if>
<else>
  <p>Party!</p>
</else>

Another way of doing that in Spark (writing the condition inside the <p> tag):

<p if='DateTime.Now.Hour > 20 || DateTime.Now.Hour < 6'>
  It's bed time!
</p>
<else>
  <p>Party!</p>
</else>

 

NHaml

- if (DateTime.Now.Hour > 20 || DateTime.Now.Hour < 6)
  %p= "It's bed time!"
- else
  %p= "Party!"

 

Loops

Here I’m comparing the way to declare a list in the view and create an <ul>-<li> HTML list out of it.

The Web Forms View Engine

<% var list = new List<string>() { "WebForms", "Razor", "Spark", "NHaml" }; %>
<ul>
<% foreach (var item in list) { %>
  <li><%: item %></li>
<% } %>
</ul>

 

Razor

@{ var list = new List<string>() { "WebForms", "Razor", "Spark", "NHaml" }; }
<ul>
@foreach (var item in list) {
  <li>@item</li>
}
</ul>

 

Spark

<var list='new List<String>() { "WebForms", "Razor", "Spark", "NHaml" }'/>
<ul>
  <li each='var item in list'>
    ${item}
  </li>
</ul>

 

NHaml

- var list = new List<String>() { "WebForms", "Razor", "Spark", "NHaml" }
%ul
  - foreach (var item in list)
    %li= item

 

Displaying a Form

Here I’m comparing the way to write a login form. I’m using the login form from the default ASP.NET MVC 2 template (located at Views/Account/LogOn.aspx). Notice that it is based on a model of type Demo.Models.LogOnModel (located inside Models/AccountModels.cs).

The Web Forms View Engine

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Demo.Models.LogOnModel>" %>

<% using (Html.BeginForm()) { %>
    <%: Html.ValidationSummary(true, "Login was unsuccessful.") %>
    <div>
        <fieldset>
            <legend>Account Information</legend>
                
            <div class="editor-label">
                <%: Html.LabelFor(m => m.UserName) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(m => m.UserName) %>
                <%: Html.ValidationMessageFor(m => m.UserName) %>
            </div>
                
            <div class="editor-label">
                <%: Html.LabelFor(m => m.Password) %>
            </div>
            <div class="editor-field">
                <%: Html.PasswordFor(m => m.Password) %>
                <%: Html.ValidationMessageFor(m => m.Password) %>
            </div>
                
            <div class="editor-label">
                <%: Html.CheckBoxFor(m => m.RememberMe) %>
                <%: Html.LabelFor(m => m.RememberMe) %>
            </div>
                
            <p>
                <input type="submit" value="Log On" />
            </p>
        </fieldset>
    </div>
<% } %>

 

Razor

@model Demo.Models.LogOnModel

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true, "Login was unsuccessful.")
    <div>
        <fieldset>
            <legend>Account Information</legend>
                
            <div class="editor-label">
                @Html.LabelFor(m => m.UserName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.UserName)
                @Html.ValidationMessageFor(m => m.UserName)
            </div>
                
            <div class="editor-label">
                @Html.LabelFor(m => m.Password)
            </div>
            <div class="editor-field">
                @Html.PasswordFor(m => m.Password)
                @Html.ValidationMessageFor(m => m.Password)
            </div>
                
            <div class="editor-label">
                @Html.CheckBoxFor(m => m.RememberMe)
                @Html.LabelFor(m => m.RememberMe)
            </div>
                
            <p>
                <input type="submit" value="Log On" />
            </p>
        </fieldset>
    </div>
}

 

Spark

<viewdata model="MvcApplication1.Models.LogOnModel"/>

# using (Html.BeginForm()) {
    ${Html.ValidationSummary(true, "Login was unsuccessful.")}
    <div>
        <fieldset>
            <legend>Account Information</legend>
                
            <div class="editor-label">
                ${Html.LabelFor(m => m.UserName)}
            </div>
            <div class="editor-field">
                ${Html.TextBoxFor(m => m.UserName)}
                ${Html.ValidationMessageFor(m => m.UserName)}
            </div>
                
            <div class="editor-label">
                ${Html.LabelFor(m => m.Password)}
            </div>
            <div class="editor-field">
                ${Html.PasswordFor(m => m.Password)}
                ${Html.ValidationMessageFor(m => m.Password)}
            </div>
                
            <div class="editor-label">
                ${Html.CheckBoxFor(m => m.RememberMe)}
                ${Html.LabelFor(m => m.RememberMe)}
            </div>
                
            <p>
                <input type="submit" value="Log On" />
            </p>
        </fieldset>
    </div>
# }

 

NHaml

- using (Html.BeginForm())
  =Html.ValidationSummary(true, "Login was unsuccessful.")
    %div
      %fieldset
        %legend Account Information
        %div.editor-label
          =Html.Label("UserName")
        %div.editor-field
          =Html.TextBox("UserName")
          =Html.ValidationMessage("UserName")
        %div.editor-label
          =Html.Label("Password")
        %div.editor-field
          =Html.Password("Password")
          =Html.ValidationMessage("Password")
        %div.editor-label
          =Html.CheckBox("RememberMe")
          =Html.Label("RememberMe")
        %p
          %input{type="submit" value="Log On"}

 

Conclusion

This was a quick comparison of the most basic features of the web forms view engine, Razor, Spark and NHaml. As you could see, they all support the same things but each takes it to its own direction.

Which one did you like the most?

All the best,
Shay.

kick it on DotNetKicks.com Shout it




Subscribe Subscribe

That's Me!

Hi! I'm Shay Friedman
I'm Shay Friedman - a Visual C#/IronRuby MVP, a consultant and instructor of .NET technologies, author, speaker and new technologies freak
More about me

Contact Me

> Contact page
> Twitter: @ironshay
> LinkedIn profile

Search

Hosted By

I'm hosting this site on Arvixe and I'm very happy with it.
If you're looking for ASP.NET hosting, I highly recommend it
(and if you order from this link I also get some beer money!)
Web Hosting