Wednesday, March 30, 2011

Say hello to Asp.net Razor web site. Part2 : Basic concepts


DARE TO SHARE?
Introduction

The previous part of this article introduces with an Asp.net Razor web site, which is built on top of Razor view engine. This part will cover some basic Razor stuff which would be kind of essentials to know, in order to develop an Asp.net Razor web site based application.

Here we go

As you might know already, unlike the Asp.net Web Forms, there is no Server control or CodeBehind classes available in Razor web sites. All you have is the cshtml files, which contains the plain old html markups with simple Razor expressions @. In Razor, you stay closest to the basic HTML, that gives you the power to customize the front-end functionality to your heart's content. The good news is, even though you don't have the powerful server controls here, you've got powerful built-in Helpers which lets you add complex user interface modules with functionality in the cshtml pages. Razor is simple, and beautiful.

Following are some of the basic Razor things that you should know, in order to be able to start building a real application:

The IsPost property

Like the IsPostBack property in Asp.net web forms, you can determine whether the current Request is due to a form Post or Get request by checking the IsPost property as follows:

@{  
    Layout = "~/_SiteLayout.cshtml";
}

@{
    if(IsPost) 
    {
        // Retrieve the numbers that the user entered.
        var user = Request["UserName"];
        var password = Request["Password"];
        UserManager userManager = new UserManager();
        var success = userManager.TryLogin(user, password);
    }
}

<p>Enter UserName and Password</p>
<form action="" method="post">
  <p>
    <label for="text1">UserName:</label>
    <input type="text" name="UserName" />
  </p>
  <p>
    <label for="text2">Password:</label>
    <input type="text" name="Password" />
  </p>
  <p>
    <input type="submit" value="Login" />
  </p>
</form>  

Mixture of HTML and Razor

In Razor, @ is just a replacement of the server side expression <%=%> and <%...%> which are using in aspx web forms. Using the @ symbol doesn't require you to end the expression with something, which greatly simplifies the mixture of HTML markups and server side expressions and improves readability a lot.

Have a look at the following codes:

@if(IsPost) {
<p>
      You submitted data at <b>@DateTime.Now</b>
    </p> 
}
else {
   <p>
     Today is @DateTime.Now and system welcomes you
   </p> 
}

The basic rule is, you start any server side expression with @, and, you don't need to end it. All of the other programmatic syntax should be there as they should be, like, if you open the curly brace "{", you need to close it "}".

Comments

@*  A one-line code comment. *@

@*  This is a multiline code comment.     
It can continue for any number of lines. 
*@

The @Href method

For resolving correct relative paths for resources in HTML, the @Href method is your good friend. The WebPage object (The current object of the page, equivalent to the Page object in WebForms) has this handy method, which could be used as follows to resolve correct relative paths:

<link href="@Href("~/Styles/Site.css")" rel="stylesheet" />
<link href="@Href("~/favicon.ico")" rel="shortcut icon" type="image/x-icon" />

Including another page using @RenderPage()

The layout pages contain a @RenderBody()  method, which is replaced by the content of a child page at run-time. Using the layout page thus gives a way to have consistent look of the entire site.

Much like the @RenderBody(), there is another way you can include the output of an another page in an existing page. The @RenderPage(PageName) method allows such facility. For example, a layout page could have a @RenderPage(PageName) to include the output of another page in it. It works much like adding a User Control in an aspx page.

_SiteLayout.cshtml

<!DOCTYPE html>
  <head>
    <title> Title </title>
    <link href="@Href("/Styles/Site.css")" rel="stylesheet" type="text/css" />
  </head>
  <body>
    @RenderPage("/_Header.cshtml")
    <div id="main">
      @RenderBody()
    </div>
    <div id="footer">
      &copy; 2010 SmartAspects. All rights reserved.
    </div>
  </body>
</html>

Passing data to Layout page

Passing data from the content page to Layout page is a very basic need. Pages in Razor has a PageData property which is used for this purpose. The following example shows passing Page title from the content page to the Layout page:

Layout Page:

<!DOCTYPE html>

<html>
    <head>
      <title>@PageData["Title"]</title>
    </head>
    <body>
        ...
    </body>
</html> 

Child Page

@{  
  Layout = "~/_SiteLayout.cshtml";
  PageData["Title"] = "User details page";
}

Helpers

A helper is a component that lets you accomplish a task using a single line of code. ASP.NET includes many built-in helpers which are ready to be used in cshtml files, such as the following, which displays data in Grid layout using the built-in WebGrid helper:

@{
    var db = Database.Open("DBConn") ;
    var query = "SELECT * FROM Product ORDER BY Id";
    var data = db.Query(query );
    var grid = new WebGrid(data);
}
<!DOCTYPE html>
<html>
    <head>
        <title>Displaying Data Using the WebGrid Helper</title>
    </head>
    <body>
        <h1> Products</h1>
        <div id="grid">
            @grid.GetHtml()
        </div>
    </body>
</html>

There are many built-in helpers which you could use to achieve several necessary functions and features. Some are as follows:

The WebCache helper : Lets you using Caching in cshtml pages as follows:

@{
    var data = WebCache.Get("Key");

    if (data == null) {
        data = "Test";
        WebCache.Set("Key", data, 1, false);
    }
}

The FileUpload helper : Lets you upload single or multiple files

<html>
    <head><title>FileUpload - Multiple File Example</title></head>
<body>
    <form id="myForm" method="post"
       enctype="multipart/form-data"
       action="">
    <div>
    <h1>File Upload - Multiple-File Example</h1>
    @if (!IsPost) {
        @FileUpload.GetHtml(
            initialNumberOfFiles:5,
            allowMoreFilesToBeAdded:true,
            includeFormTag:true,
            addText:"Add another file",
            uploadText:"Upload")
        }
    </div>
    </form>
</body>
</html>

The Video helper : Lets you include a Video in the page

<!DOCTYPE html>
<html>
<head>
    <title>Flash Video</title>
</head>
<body>
    @Video.Flash(path: "Media/sample.swf",
                 width: "400",
                 height: "600",
                 play: true,
                 loop: true,
                 menu:  false,
                 bgColor: "red",
                 quality: "medium",
                 scale: "exactfit",
                 windowMode: "transparent")
</body>
</html>

The WebMail helper : Lets you send emails

@{
    try {
        // Initialize WebMail helper
        WebMail.SmtpServer = "smtp.mydomain.com";
        WebMail.SmtpPort = 25;
        WebMail.EnableSsl = true;
        WebMail.UserName = "user";
        WebMail.From = "shubho@smartaspects.com";
        WebMail.Password = "123456";
        var mailBody = Utility.GetEmailBody();
        // Send email
        WebMail.Send(to: "user@example.com",
            subject: "Newsletter for - " + customerName,
            body: mailBody 
        );
    }
    catch (Exception ex ) {
        <text>
            <b>Failed to send email.</b>
        </text>
    }
}

The Bing helper : Lets you add a search functionality with Bing search engine

@{
    Bing.SiteUrl = "www.asp.net";
    Bing.SiteTitle = "ASP.NET Custom Search";
}
<!DOCTYPE html>
<html>
    <head>
        <title>Bing Search Box</title>
    </head>
    <body>

    <div>
       Search the ASP.NET site: <br/>
       @Bing.SearchBox()
    </div>

    <div>
       <h1>Advanced Search</h1>
        Search the ASP.NET site: <br/>
        @Bing.AdvancedSearchBox(
            boxWidth: "300px",
            resultWidth: 600,
            resultHeight: 900,
            themeColor: "Green",
            locale: "en-US")
        </div>
    </body>
</html>

The LinkShare helper.
The Twitter helper.
The Facebook helper.
 
These let you add social network functionality in cshtml pages

The WebSecurity helper.
The SimpleMembership helper.
The ReCaptcha helper.

These let you implement user registration and login functionality with Membership

Custom helpers

You also may want to create and use custom helpers in your application and use that helper across the pages for a consistent look and functions. Here is how you can do this:

1. Add the App_Code folder in your web site
2. Create a new .cshtml file inside App_Code folder  and name it Helpers.cshtml.
3. Replace the existing content with the following and save the file:

@helper BuildMessage(string user) {
    <div class="message">
      <p>
          <strong>Hello</strong>&nbsp;&nbsp; @user!
       </p>
    </div>
}

Once created, you can use the helper as follows:

<!DOCTYPE html>
  <head>
    <title>Helpers Page</title>
  </head>
  <body>
    @Helpers.BuildMessage("My test note content.")
  </body>
</html>

Further study

Enjoyed Razor? Does it seem interesting? See http://www.asp.net/webmatrix/tutorials/1-getting-started-with-webmatrix-and-asp-net-web-pages for more detailed on Asp.net Razor and keep exploring, Razor is fun.