Tuesday 7 January 2014

Razor View Engine in ASP.NET MVC3


  • The Razor View Engine is new to ASP.NET MVC 3 and is the default view engine for future.
  • Razor is the response to one of the most requested suggestion received by ASP.NET MVC feature team. 
  • The suggestion is to provide a clean, lightweight simple view engine that did not contain the syntactic cruft contained in the exisiting Web Forms View Engine.
  • The request was finally answered in version 3 of ASP.NET MVC by introducing a new Razor View Engine.


Features:

Razor provides a streamlined syntax for expressing views that minimizes the amount of syntax and extra characters.

1. Compact, expressive, and fluid: Razor syntax makes very simple to express your coding intent. Razor also simplifies markup with an improvement on the Master Pages concept called Layouts. Layouts are more flexible and and requires less code. The @character is used to signify the transition from markup to code, and the Razor engine automatically detected the transition back to markup.

2. Not a new Language: Razor is not a new language. It is a syntax that lets you use your existing .NET coding skills in a template in a very intuitive way.


3. Easy to learn: As Razor is not a new language, it is easy to learn. You need to know HTML, .NET and need to type HTML and hit the @ sign whenever you need to write some .NET code.


4. Works with any text editor: Razor is so lightweight and HTML-focused, we can use any text editor of our choice. Visual studio's syntax highlighting and intelliSense features are nice, but it's simple enough that you can edit it in any text editor.

A simple View :

    @{
    ViewBag.Title = "Home";

    var cars = new string[] { "city", "civic", "accord" };
}

<html>
<head><title>Home</title></head>
<body>
<h1>List of Cars :</h1>
<ul>
@foreach (var car in cars)
{
    <li>@car</li>
}
</ul>
</body>
</html>

The above code sample uses c# syntax. The file has .cshtml extension. Similarly, Razor views which uses the Visual Basic syntax will have .vbhtml file extension. These extensions are important as they signal the code language syntax to the Razor parser.

Code Expressions:


The key transition character in Razor is the @ sign. The single character is used to transition from HTML markup to code and sometimes also to transition black.

       There are two basic types of transitions :

  • Code Expressions 
  • Code Blocks

Code expressions are evaluated and written to the response. We will explain multiple scenarios in Code Expression by different examples.

Case 1:



    <h1>I have @Cars.Length cars.</h1>

The expression @Cars.Length is evaluated as an implicit code expression and the output displayed is 2 on UI. We did not need to demarcate the end of the code expression. In contrast, with a Web Forms View, which supports only explicit code expressions, the above code would look like:

    <h1>I have <%: Cars.Length %> cars.</h1>

Note: Razor is smart enough to know that the space character after the expression is not a valid identifier, so it transitions smoothly back into markup.

Case 2:



    <h1>List of Cars :</h1>
<ul>
@foreach (var car in cars)
{
    <li>@car.</li>
}
</ul>

In above example, the character after the @car code expression is valid code character. Now the question arises that how does razor knows that the dot after the code expression is not meant to start referencing a method or property of current expression. Razor is smart to peeks to next character to find opening angle bracket , which is not a valid identifier and transitions back to markup rendering the li element.
                This ability of Razor to automatically transition back from code to markup is one of its big appeals and is secret sauce in keeping the syntax compact and clean.

Case 3:



    @{
        string rootNamespace = "MyApplication";
    }
    <span>@rootNamespace.Models</span>

In the above case, we expect output to be "MyApplication.Models", instead we get an error saying String does not contain a definition for Models. In this case Razor could not understand out intent and thought that @rootNamespace.Models was our code expression. Razor provides a way to handle this case, it supports explicit code expression by wrapping the expression in paranthesis as shown below :

    @{
        string rootNamespace = "MyApplication";
    }
    <span>@(rootNamespace).Models</span>

The above code tells Razor that the .Models is literal text and not part of the code expression.

Case 4:



    <span>20Fingers2Brains@gmail.com</span>

At first glance, it seems like the above code will cause an error because @gmail.com looks like a valid code expression where we are trying to print out com property of gmail variable. Fortunately, Razor recognize the general pattern of an email address and will leave this expression alone.

Case 5:



        <li>Item_@Item.Length</li>
    
In the above case we have code expression similar to email address, but in this case we mean it to be an code expression. The Razor will print out the text as it matches the email adress pattern whereas we expected Razor to print out Item_3.
                 Once again, parentheses to the rescue! Whenever there is an ambiguity in razor for code expression use parentheses  to explicitly convey about the code expression as shown below:

        <li>Item_@(Item.Length)</li>
    
Case 6:

        <p>
        You should follow
        @20Fingers2Brains, @MVC3, @Razor
        </p>
    

In the above case we want to display some Twitter handles, which starts with @ sign. In this case Razor is going to resolve the implicit code expressions and would fail. In this case where you need to escape the @ sign, you can do so by using a double  @@ sign as shown below:

        <p>
        You should follow
        @@20Fingers2Brains, @@MVC3, @@Razor
        </p>
    

HTML Encoding:
There are numerous scenarios where a view is used to display user input, there is always the potential for cross-site script injection attacks. The good news for us is that Razor expressions are HTML encoded.


        @{
            string message = "<script>alert('hello world');</script>";
        }
        <span>@message</span>
    
The above code will not result in an alert box instead display an encoded message.
However, in cases where you intend to show HTML markup, you can return an instance of System.Web.IHtmlString and Razor will not encode it. All the view helpers in Razor MVC3 return instances of this interface. We can also create an instance of HtmlString or use Html.Raw helper method.

        @{
            string message = "<strong>20Fingers2Brains</strong>";
        }
        <span>@Html.Raw(message)</span>
    
The above code will result in message being displayed without HTML encoding as shown below:

        <span><strong>20Fingers2Brains</strong&gt;</span>
    
This automatically HTML encoding is great for mitigating XSS vulnerabilities by encoding user input meant to be displayed as HTML, but it is not sufficient for diaplying user input within JavaScript.
For Example:


        <script>
            $(function () {
                var message = 'hello @ViewBag.Username';
                $("#message").html(message);
            });
        </script>
    

In the above code, a JavaScript variable message is set to a string, which includes the value of user-supplied user name. The user name comes from a Razor expression.
                         Using the jQuery html method the message is set to be the HTML for DOM element with id message. In above case even thought the user name is HTML encoded withing the message string, there is still a potential XSS vulnerability.
When setting variables in JavaScript by values supplied by user, it is important to use JavaScript encoding not just HTML encoding. We can use @Ajax.JavaScriptStringEncode to encode the input as shown below:


        <script>
            $(function () {
                var message = 'hello @Ajax.JavaScriptStringEncode(ViewBag.Username)';
                $("#message").html(message);
            });
        </script>
    

Code Blocks:
In addition to code expressions, Razor also supports code blocks within a view.
    @foreach (var car in cars)
{
    <li>@car</li>
}

The above block of code iterates over an array and displays a list item for each item in array. The interesting thing about the above statement is how the foreach statement automatically transitions to markup.
                        Code blocks require curly braces to delimit the block of code in addition to an @ sign.

For Example:



        @{
            string message = "Hello world";
            ViewBag.Title = "About Us";
        }
    
The above is the simplest example of code block. Another example of code block where the called method does not return a value (return type is void):

        @{Html.RenderPartial("HomePartial");}
    
We do not require curly braces for block statements like foreach loops and if statements.


No comments:

Post a Comment