Tuesday, 10 June 2014

ASP.NET MVC 4 - Part [3] - Razor View Engine and ASPX View Engine


Table Of Contents  
 

Introduction  

View Engines are responsible for rendering the HTML from your views to the browser. The view engine template will have different syntax for implementation. Currently there are few number of view engines available for MVC and In this article we will go through the Razor and ASPX view engine. I have listed some of the available view engines for ASP.NET MVC in another article , click here read more on different view engines.
In this article I will take you through the Razor, the most opted view engine and the ASPX, the legacy view engine.  

@Razor 

The Razor view engine is an advanced view engine from Microsoft, packaged with MVC 3. Razor using an character instead of aspx's <% %> and Razor does not require you to explicitly close the code-block, this view engine is parsed intelligently by the run-time to determine what is a presentation element and what is a code element.  
In my opinion Razor is the best view engine available for MVC as its much cleaner and easy to write and read. This view engine is compatible with unit testing frameworks. It is very difficult to implement unit test with ASPX view engine and the other available view engines doesn't provide anything related to testablity in their respective sites.  
This is the default view engine in MVC 3 and MVC 4. Web pages with Razor syntax have the special file extensioncshtml (Razor with C#) or vbhtml (Razor with VB).  

<%ASPX%>  

The syntax for writing views with this engine is the same syntax that the ASP.NET Web Forms uses and the file extensions are also taken from ASP.NET Web Form (.aspx, .ascx, .master) . The coding will give us the memory of legacy ASP style.  
This is the default view engine for MVC 1 and MVC 2.  
Let us start exploring the syntax differences and other major points.

Syntax/Usage 

If you came from the legacy ASP style coding then you will feel much comfortable with ASPX View Engine and if you are comfortable with C# language then you can easily go with Razor view engine. Let's go thrugh how we can use Razor and or ASPX view engine in our application. 
Let's start reviewing some of the usages
Note: All code samples are given in C# language. All Sample code outputs are shown at the end.  [Codes are for demonstration purpose and may not be following all best practices]. 

Comment   

Comments in Razor syntax are delimited by @* *@ where as ASPX comments are delimited by <%-- --%> 
@*My Razor Comment*@   
<%--My ASPX Comment--%>  
If you are inside a C# code block then you can also use // and /* */ comment delimiters. The below code shows comments in side a c# code block. 
@{
    //Razor
    //Single line comment
    /* Multi
       line comment
    */
} 
<% 
//ASPX   
//Single line comment
/* Multi
line comment
*/ 
%> 

Code Block 

We can easily write server side code blocks in the source html itself. 
@{ 
    string ViewEngine = "Razor";
    string CodeIn = "C#";
    string SpanClass = "boldclass";
    bool isMale = true;
    string[] Products = new string[] { "Computer", "Mobile", "Watch", "Television" };
} 
The above code decalares some server side variables and the variables are got initialized with appropriate data in it.  
The above code block is written in a .cshtml file (Razoe C#). Below, the same code is written in .aspx (ASPX C#). 
<%  
    string ViewEngine = "ASPX";
    string CodeIn = "C#";
    string SpanClass = "boldclass";
    bool isMale = true;
    string[] Products = new string[] { "Computer", "Mobile", "Watch", "Television" };
%> 
The above declared variables will be used in the coming sections. 

Code and Markup  

When working in a dynamic web page we often required to mix code and html,  This section will expalin how code and markup can be used together in ASPX and Razor view engine.  

Text and Markup  

If you see the below code, I have used the previously declared variable inside an html tag and the view engine will intelligently parse the code in between the html tags. 
<span>@ViewEngine</span> 
The above code is written for Razor(C#) and the below code will acheive the same in ASPX(C#) view engine.  
<span><%:ViewEngine %></span> 
Suppose if you want to include a plain text inside a code block then we can use the <text> tag or @: for Razor view engine.
@if (isMale)
{
    <text>Sex:Male</text>
}
else
{
    <text>Sex:Female</text>
} 
The above code used <text> tag for adding a plain text inside a code block and we can acheive the same using @:also, 
@if (isMale)
{   
    @:Sex:Male
}
else
{
    @:Sex:Female
} 
In ASPX view engine we can simply acheive the above plain text functionality by the below code, 
<% if (isMale)
   { %>
    Sex:Male 
<% }
else
   { %>
    Sex:Female
<% } %>  
So now you might be thinking how can we have some expression with a plain text, well it's simple.
I write code in @ViewEngine (@CodeIn)
I write code in <%:ViewEngine%> (<%:CodeIn %>) 
The above code will rendered with the value of ViewEngine and CodeIn variable. 

Html Encoded

Html encoded values are acheived by the below codes. 
Raxor 
<span>@ViewEngine</span> 
ASPX 
<span><%:ViewEngine%></span> 
If you don't want to encode the data then you can use the Html Unencoded format.  

Html Unencoded 

In Razor @Html.Raw is used for rendering Unencoded values and in ASPX <%= %> is used for the same. 
<span>@Html.Raw(ViewEngine)</span> 
<span><%=ViewEngine%></span> 

Dynamic value inside an Html Attribute 

If you came across a situation where the html element's attribute values needs to be changed conditionally then this approach will be very useful. Below, you can see the <span> element  class is aasigned with a server side variable. 
<span class="@SpanClass">@ViewEngine</span> 
The above code was written for Razor(C#) and the same can be achived for ASPX(C#) as below. 
<span class="<%:SpanClass%>"><%:ViewEngine%></span>  
We can have other literals together with the server side variable. See the below example where @SpanClass evaluated to a string value and rendered with the string literals fontClass and blueClass
<span class="@SpanClass fontClass blueClass">@ViewEngine</span>  
The below code shows the same in ASPX view engine. 
<span class="<%:SpanClass%> fontClass blueClass"><%= ViewEngine %></span> 
below sample sets a boolean server side variables value as checkbox's checked property. 
<input type="checkbox" checked="@isMale" /> 
<input type="checkbox" checked="<%:isMale%>" />    

Explicit Expression 

Explicit expression is very useful in below situations, below sample code is written for Razor(C#).  Here instead of a IF conditional statement I have used conditional operator inline. 
<span>Sex:@(isMale ? "M" : "F")</span> 
Sample of explicit expression in ASPX(C#)  
<span>Sex:<%: isMale ? "M" : "F" %></span>  

File Path  

Form Razor2 we can easily use "~/" for file path where as before Razor2 we used the below codes for the same. 
Url.Content("~/...") or @Href("~/...")   
Razor2 
"~/"   

Conditional Statement 

Conditional statement sample for Razor (C#). 
@if(isMale)
{   
  <p>Sex:Male</p>
} else {
  <p>Sex:Female</p>
} 
Conditional statement sample for ASPX (C#).  
<% if (isMale)
{ %>
    <p>Sex:Male</p>
<% }
else
{ %>
    <p>Sex:Female</p>
<% } %> 
The above usage gives us a very easy approach for rendering things conditionally. 

Looping Statement 

The below satement in Razor view engine is used for rendering the prouct list. 
<ul>
    @foreach (var item in Products)
    {
        <li>@item</li>
    }
</ul> 
Razor view engine is smart enough to identify the <li> tag as an html tag and the @item as a server side value. The<li> will be rendered multiple times with the list of products.
Below satatemet is used for ASPX view engine to output the same as above. 
<ul>
    <%foreach (var item in Products)
        {  %>
    <li><%=item%></li>
    <%} %>
</ul>  

Calling Server Side Method

To demonstrate this I have created a static method named ServerSideCode in a class and called inside a <p> tag using the appropriate view engines syntax.  
<p>@{RazorASPXViewEngine.Models.SampleUtility.ServerSideCode();}</p> 
This code will be rendering with the output returned from the ServerSideCode() 
<p><%=RazorASPXViewEngine.Models.SampleUtility.ServerSideCode();%></p> 

Creating a Delegate 

Razor delegates are nothing but they are templates build by C# and HTML. Check more details from Phil Haack article on Templated Razor Delegates.
As I'm aware of the type. I have used Func<string[], object> instead of using Func<dynamic, object>. and I have used the magic 'item' to get the value inside the Func<>
@{
    Func<string[], object> ProductListing = 
    @<ul>
        @foreach (string p in item)
        {
            <li>@p</li>
        }
   </ul>;
}

Product listing from delegate-
@ProductListing(Products); 

Creating a method 

The @functions block in Razor helps you to define utility functions directly in the view.  
@functions{
    public string myName()
    {
        return "Shemeer";
    }
}
Name:@myName(); 
This functions should be created only when the function is specific to the view and can't be done using other conditional statement.  By using @function we can separate view specific logic from controller. 

Escape Character  

Razor language parser is very smart to konw the @ symbol is used for a static content or dynamic content. Let's examine the below code lines. 
@@@CodeIn
@@CodeIn
shemeerns@facebook.com   
The fist line will print @C# where as the second line will print @@CodeIn. The third one will be parsed intelligently by the parser and will print the email address shemeerns@facebook.com. The second line printed @@CodeIn because of the escape symbol the variable will not be considered/evaluated. 
To escape an @ symbol just add @@ and it will render a single @ symbol. 

Comparison 

Below, I have listed some of the comparisons with ASPX and Razor view engines. 
  • Razor uses @ symbol whereas ASPX uses <% %>.  
  • Razor view engine is launched with MVC3 and it's the defualt view engine from MVC3 where as ASPX view engine was there from the initial version and ASPX is default view engine for MVC 1 and MVC 2. 
  • File extensions are different for Razor (C#-cshtml, VB-vbhtml) and ASPX(aspx, ascx, master) 
  • For acheiving similiar functionality Razor requires very less number of keystrokes compared to ASPX. 
  • Razor sytax is very clean and easy to learn than ASPX view engine. 
  • Razor very much supports TDD (Test Driven Devolopment). 
  • Namespace for Razor is System.Web.Razor and for ASPX it's System.Web.Mvc.WebFromViewEngine 
  • Razor view engine is little slower than ASPX view engine.  

Conclusion 

So what's your preference, Razor or ASPX or any other view engines? 
I would go for Razor beacuase of the lightweight syntax, readability, maintanability, TDD, and more.
The below given picture is taken from an online poll where they were asking the user choices of view engine, 
Razor vs ASPX Other View Engines 

Using attached Code  

I have attached an MVC4 sample application with all the above samples. The ASPX view looks like below,
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
 
<!DOCTYPE html>
 
<html>
<head runat="server">
    <meta name="viewport" content="width=device-width" />
    <title></title>
</head>
<body>
    <div>
        Select View Engine : <%=(Html.ActionLink("Razor", "RazorIndex", "Home")) %>  | <%=(Html.ActionLink("ASPX", "ASPXIndex", "Home")) %>
        <br />
        <%  
            string ViewEngine = "ASPX";
            string CodeIn = "C#";
            string SpanClass = "boldclass";
            bool isMale = true;
            string[] Products = new string[] { "Computer", "Mobile", "Watch", "Television" };
        %>
        <br />
        <span class="<%:SpanClass%> fontClass blueClass"><%= ViewEngine %></span>
        <br />
        <input type="checkbox" checked="<%: isMale%>" />
        <br />
        <span>Sex:<%: isMale ? "M" : "F" %></span>
        <br />
        <% if (isMale)
           { %>
        <p>Sex:Male</p>
        <% }
           else
           { %>
        <p>Sex:Female</p>
        <% } %>
        <br />
        <% if (isMale)
           { %>
    Sex:Male 
        <% }
           else
           { %>
    Sex:Female
        <% } %>
        <br />
        I write code in <%:ViewEngine%> (<%:CodeIn %>) 
        <br />
        <ul>
            <%foreach (var item in Products)
              {  %>
            <li><%=item%></li>
            <%} %>
        </ul>
        <br />
        <p><%=(RazorASPXViewEngine.Models.SampleUtility.ServerSideCode())%></p>
    </div>
</body>
</html>
The output for the above page is
and the Razor view looks like below, 
Select View Engine : @Html.ActionLink("Razor", "RazorIndex", "Home") | @Html.ActionLink("ASPX", "ASPXIndex", "Home")
<br />
 
@*Declaration and Initialization of Server Side Variables*@
@{ 
    string ViewEngine = "Razor";
    string CodeIn = "C#";
    string SpanClass = "boldclass";
    bool isMale = true;
    string[] Products = new string[] { "Computer", "Mobile", "Watch", "Television" };
}
 
 
@*Definition of myName function*@
@functions{
    public string myName()
    {
        return "Shemeer";
    }
}
Name:@myName();
<br />
<span class="  @SpanClass fontClass blueClass">@ViewEngine</span>
<br />
<input type="checkbox" checked="@isMale" />
<br />
<span>Sex:@(isMale ? "M" : "F")</span>
<br />
@if (isMale)
{   
    <p>Sex:Male</p>
}
else
{
    <p>Sex:Female</p>
}
<br />
@if (isMale)
{
    <text>Sex: Male</text>
}
else
{
    <text>Sex:Female</text>
}
<br />
@if (isMale)
{   
    @:Sex:Male
}
else
{
    @:Sex:Female
}
<br />
I write code in @ViewEngine (@CodeIn)
<br />
<ul>
    @foreach (var item in Products)
    {
        <li>@item</li>
    }
</ul>
 
<br />
 
@@@CodeIn
@@CodeIn
shemeerns@facebook.com
<br />
<p>@(RazorASPXViewEngine.Models.SampleUtility.ServerSideCode())</p>
The output for the above page is given below

You can download the application and try yourself.
Note: All the codes are just to demonstrate the functionality. 

No comments:

Post a Comment