Building Dynamic Websites with WebMatrix

Microsoft recently launched WebMatrix, a free, lightweight tool that provides the easiest way to build websites yet, using the new Razor view engine. Combined in the installation of WebMatrix are SQL Server Compact,  IIS Express, and the ASP.NET Web Pages framework that includes the Razor syntax. All of these make the process of creating and deploying WebMatrix websites simple.

This article will step you through the process of how to get the most out of WebMatrix and the new Razor view engine.

Before starting, you might want to read Part 1 in this series of articles on WebMatrix and the Web App Gallery. If you’re yet to install WebMatrix, you can download it and obtain installation instructions here.

Why use WebMatrix?

Why use WebMatrix if you already have Microsoft Visual Studio installed? The answer is ease of use. WebMatrix is targeted at beginners, hobbyist programmers, and those who like to draw on open source application resources. Visual Studio can be daunting to the inexperienced, while the WebMatrix User Interface (UI) is easy to use and understand.

Razor View Engine

Creating dynamic content in WebMatrix is easy, thanks to the new Razor view engine, which simplifies the syntax you need to use. Code previously requiring multiple angle brackets and percentage symbols can be written in Razor syntax with a single @ character. For example, if you wanted to print the date and time, you’d do this:

<p>The date and time is @DateTime.Now</p>

Performing a loop is easy too. Here’s the following code to loop through a counter and print the results to the window:

@for(int i = 0;i < 5;i++) {

    <p>@i</p>

}

Razor also has code blocks. The following example illustrates how to use them:

@{

    var message = "Code block text";

}

<!DOCTYPE html>

<html lang="en">

    <head>

        <meta charset="utf-8" />

        <title></title>

    </head>

    <body>

        <h2>@message</h2>

    </body>

</html>

Razor has simplified the markup so your code is more readable and easier to maintain.  Another benefit from using the Razor syntax is auto HTML encoding. This means that you’re reducing the possibility of XSS attacks without even having to think about it.  For example, you can print the following code using Razor syntax and be safe from the JavaScript being executed:

@("<script>alert('If this pops up you're in trouble');</script>")

The results can be seen below.

fig1

If you want to opt in and have the HTML encoding turned off, you can use Html.Raw, which guarantees the string will remain unencoded:

@Html.Raw("<script>alert('If this pops up you\'re in trouble');</script>")

Here’s the result:

fig2

Layout Pages

Rather than the Web Forms concept of using Master Pages with content placeholders to create a consistent look and feel across a website, the Razor view engine uses Layout Pages to achieve the same ends.

Let’s get going. Start up WebMatrix. Last time, we went to Site from Web Gallery, but this time, we’ll go to Site from Template. You’ll see a screen that looks like this:

fig3

We’re going to start from scratch with our site, so leave Empty Site highlighted, give your project a name in the Site Name field, and click OK.

On the next screen, click on the Files icon at lower left to see what files you have available. At this stage, it should only be a robots.txt file.

Create a new folder under the root website called Shared, either by right-clicking on your site name and then New Folder, or by clicking on the arrow beneath the New menu icon and selecting New Folder.

You can give the folder a different name if you prefer, but Shared follows the same design pattern as MVC. Add a new file called _Layout.cshtml. The underscore is important. ASP.NET by default will not serve pages that begin with an underscore.

Once the page has been created, you need to add a call to a new method called RenderBody. The position of the RenderBody method determines where the data from the content page will reside. Your layout page should look like this:

<!DOCTYPE html>

<html lang="en">

    <head>

        <meta charset="utf-8" />

        <title></title>

    </head>

    <body>

        <h1>Layout Page</h1>

        @RenderBody()

    </body>

</html>

Connecting the Content page to the Layout page is achieved by adding a Layout property to the Content page. Replace the code in the default.cshtml page with the following code:

@{

    Layout = "~/Shared/_Layout.cshtml

}

<h2>Hello world</h2>

Layout pages can also contain content that can be filled by other pages on disk. This is achieved by using the RenderPage method. This method takes one parameter, which is the location of a file, and injects that into the page. For this example, I’ll create a header file. Add a new CSHTML file to the Shared folder you created earlier and call it _Header.cshtml.  Add the following code to the file:

<h1>

    Heading here

</h1>

Using this new page is as easy as adding the following code to the _Layout.cshtml page:

<!DOCTYPE html>

<html lang="en">

    <head>

        <meta charset="utf-8" />

        <title></title>

    </head>

    <body>

        @RenderPage("~/Shared/_Header.cshtml")

        @RenderBody()

    </body>

</html>

The combined results can be seen below, running under IIS Express.

fig4

A layout page can contain multiple RenderPage methods, so it’s a nice way to separate your layout page from your content pages.

Layout pages also use the concept of sections. A layout page can only contain one RenderBody method, but may have multiple sections. To create a section, use the RenderSection method. The difference between RenderSection and RenderPage is that RenderPage reads the content from a file, whereas RenderSection runs code blocks you define in your content pages. The following code illustrates how to render a footer section:

<!DOCTYPE html>

<html lang="en">

    <head>

        <meta charset="utf-8" />

        <title></title>

    </head>

    <body>

        @RenderPage("~/Shared/_Header.cshtml")

        @RenderBody()

        <div id="footer">

            @RenderSection("footer")

            </div>

    </body>

</html>

RenderSection expects one parameter and that is the name of the section. If it’s absent, an exception will be thrown. Content pages can add data to sections by using the following code:

@section footer {

        <small>Copyright 2010</small>

}

The @section syntax is following by the name of the section, which in this case is footer. After that you define what content you want displayed. Your default.cshtml file should look like the following now:

@{

    Layout = "~/Shared/_Layout.cshtml";

}

<h2>Hello world</h2>

@section footer {

    <small>Copyright</small>

}

The footer section in the _Layout.cshtml page is required. If it’s absent, a runtime exception will occur. There are times when you don’t require a section, even though it’is defined in the layout page. To make a section optional, use the following code:

@RenderSection("footer", required: false)

Passing Data Between Content and Layout Pages

Sometimes, you have data that is defined in the content page and you need to refer to that data in the layout page. Accomplishing this is easy, thanks to the PageData property. The PageData property is a collection of name/value pairs that stores the data you need passed between pages. To demonstrate this, replace the code in the default page with this:

@{

    Layout = "~/Shared/_Layout.cshtml";

    if(IsPost) {

        PageData["PostedText"] = Request["PostedText"];

    } else {

        PageData["PostedText"] = "No data posted";

    }

}

<h2>Hello world</h2>

<form method="post">

    <input type="hidden" name="PostedText" value="Displayed text" />

    <input type="submit" value="Update Heading" />

</form>

@section footer {

    <small>Copyright</small>

}

In the code above, I’ve created a form, and when it’s submitted to the server, the IsPost method is used to determine if the incoming request has been generated by a HTTP post. If that’s the case, it changes the PageData property PostedText to the value from the hidden field input, otherwise it will store the old value. The last step is to update the layout page to use the PageData property. The following code is how the _Layout.cshtml page should look:

<!DOCTYPE html>

<html lang="en">

    <head>

        <meta charset="utf-8" />

        <title></title>

    </head>

    <body>

        @RenderPage("~/Shared/_Header.cshtml")

        <h2>@PageData["PostedText"]</h2>

            @RenderBody()

        <div id="footer">

            @RenderSection("footer", required: false)

        </div>

    </body>

</html>

Before posting the data, the page will look like this:

fig5

Once you’ve posted the data,  the text changes from No data posted to Displayed text, as below.

fig6

Creating Reusable Code with Helpers

A common problem you face when programming is to avoid duplicating code. Otherwise, it means extra work for you as a developer and can lead to a maintenance nightmare. For example, imagine you have the following code:

@{

    var items = new[] { "one", "two", "three", "four" };

}

<ul>

    @foreach(var item in items) {

        <li>@item</li>

    }

</ul>

This is fine if the code is in one place, but what if you had multiple places where you needed to render an unordered list from a collection of values? The bad option is to copy and paste the code. WebMatrix addresses this problem by introducing Web Helpers, allowing you to create code snippets that can be used in multiple locations.

To create Web Helpers, you’ll first need to create a new folder under the root directory called App_Code. Files that reside in this folder are compiled into a class at runtime. Next, add a new file to the website and call it Helpers.cshtml. Add the following code to the file:

@helper ShowList(string[] items) {

    <ul>

        @foreach(var item in items) {

            <li>@item</li>

        }

    </ul>

}

The @helper denotes a helper method. ShowList is the name of the helper, and it accepts an array of strings and renders them in an unordered list. To use this helper, use the following code in the default.cshtml page:

@{

    var items = new[] { "one", "two", "three", "four" };

    @Helpers.ShowList(items);

}

Helpers act in a similar way to a static class in .NET. You reference them by the filename and method name. @Helpers maps to the Helpers.cshtml in the App_Code folder, and ShowList is the name of the helper.

ASP.NET Web Pages Package Administration

In addition to the Web Helper you created in the previous example, there’s an easy way for you to download open source web helpers that will make your life much simpler. To download these helpers, you’ll need to use the Package Manager tool, which is part of the ASP.NET Web Pages Package Administration website. Follow these steps to install the library:

1.       Select the default.cshtml page you created earlier and click Run from the ribbon. In the Address bar in your browser, replace the default.cshtml with _Admin. Your URL should look similar to http://localhost:1234/_Admin.

2.       Press Enter to browse to the URL above. Because this is the first time you’re logging into the _Admin page, it prompts you to create a password. Enter your password and press Create Password.

3.       For security reasons, your password is saved in a file named _Password.config in the /App_Data/Admin/ folder of your website. To enable site administration, you must browse to the file and remove the underscore (_) character from the filename. By default, all sites reside in /My Documents/My Web Sites. Once you’ve completed these steps, click the Click here link. This screen is shown below.

fig7

4.       You’ll now be redirected to the login page. Enter the password and click the Login button. Once you’ve logged in, the Package Manager displays any installed packages.

5.       Click the Show drop-down box and select Online. This option displays a web-based feed that contains a list of add-on packages you can install. Click the Install button for the package named ASP.NET Web Helpers Library 1.1. A details page displays more information and a license agreement for the package.

fig8

6.       On the details page, click Install again to install the package. Once installed, the Package Manager displays the result.

7.       Repeat steps 6 and 7 to install the Facebook.Helper 1.0 package. This package includes the Facebook helper, which makes it easy to integrate Facebook into your application.

There are numerous Web Helpers available in both libraries. You’ll see how easy it is to use these Web Helpers to create dynamic content.

Facebook

The Facebook helper is designed to integrate your WebMatrix site with Facebook, making it possible to add the Facebook Social Plugins, such as the Like Button, Facepile, Comments, Login Button, and Like Box in a few simple steps. It also allows you to easily integrate your site with the Facebook login mechanism, so there’s no need for users to create another account just to access your website. Some of the helpers require initialization, which means you need to explicitly give the helper access to your Facebook account. First, let’s take a look at some of the helpers that don’t require initialization.

LikeButton

The LikeButton displays a Facebook Like Button. When the user clicks the Like Button on your site, a story appears in the user’s friends’ News Feed with a link back to your website. Add the following code to start using the helper:

<!DOCTYPE html>

<html lang="en">

    <head>

        <meta charset="utf-8" />

        <title>Facebook Helpers</title>

    </head>

    <body>

        <img src="http://1.sitepointstatic.com/frontpage/images/logo.png" alt="Sitepoint" /><br/><br/>

        @Facebook.LikeButton("http://www.sitepoint.com/")

    </body>

</html>

The image below displays the button for liking the SitePoint home page.

fig9

ActivityFeed

The activity feed helper displays stories—both when users “like“ content on your site, and when users share content from your site back to Facebook. Add the following code to start using the helper:

<!DOCTYPE html>

<html lang="en">

    <head>

        <meta charset="utf-8" />

        <title>Facebook Helpers</title>

    </head>

    <body>

        <img src="http://1.sitepointstatic.com/frontpage/images/logo.png" alt="Sitepoint" /><br/><br/>

        @Facebook.ActivityFeed(site: "http://www.sitepoint.com/")

    </body>

</html>

This image displays SitePoint’s recent activity on Facebook.

fig10

The helpers in the previous examples required no initialization. Now let’s take a look at some helpers that do, and how you can set up initialization. To begin with, make a note of the Site URL where your site is running. Click on the Site workspace, and then Settings.

fig11

Next, you’ll need to navigate to http://www.facebook.com/developers/createapp.php and register a new Facebook application. Make note of the Application Id and Secret,—you’ll need to log into your Facebook account for this. Once you’re logged in, enter the application name and click Create App, as shown below.

fig12

Once you’ve passed the security check, you’ll be able to enter in the site details. This screen also includes the Application ID and Application Secret, which are needed for your site. When creating your Facebook application, make sure you set the Site Url to http://localhost:[port]/, replacing the [port] placeholder with the port where your local WebMatrix site is running (as shown below).

Click Save Changes when you’re finished. Let’s now take a look at the Comments helper.

Comments

The Comments shows Facebook comments. The comments box easily enables your users to comment on your site’s content. The first step is to add the Initialize helper and pass in the Application ID and Application Secret from the previous section:

@{

    Facebook.Initialize("{your App ID}", "{your App Secret}");

}

Once that’s done, the next step is to is add the FbmlNamespaces, GetInitializationScripts, and Comments helpers. This code is all you need to enable Facebook comments:

@{

    Facebook.Initialize("xxxxxxxxxxxxxxx", "xxaxaaxxaxaxxxaxaxxxxaaxaxxxaxax");

}

<!DOCTYPE html>

<html @Facebook.FbmlNamespaces()>

    <head>

        <meta charset="utf-8" />

        <title>Facebook Helpers</title>

    </head>

    <body>

        @Facebook.GetInitializationScripts()

        @Facebook.Comments()

    </body>

</html>

The result can be seen here.

fig13

For a full list of the Facebook helpers, go to http://facebookhelper.codeplex.com.

Twitter

The TwitterGoodies helper is designed to integrate your WebMatrix site with Twitter, making it possible to add functionality such as access to searches and user profiles in a few simple steps. Let’s take a look at some of the helpers and see how easy it is to make this work.

Profile

The Profile helper loads a Twitter profile. If you want to view the up-to-date tweets from SitePoint, here’s the code:

<!DOCTYPE html>

<html>

    <head>

        <meta charset="utf-8" />

        <title>Twitter Helpers</title>

    </head>

    <body>

        @TwitterGoodies.Profile(username: "sitepointdotcom")

    </body>

</html>

The result is shown here.

fig14

Search

The Search helper gives you the ability to search Twitter. The search can be based on trends or profiles. The following code adds the helper to your page, which automatically updates with the latest searches for SitePoint:

<!DOCTYPE html>

<html>

    <head>

        <meta charset="utf-8" />

        <title>Twitter Helpers</title>

    </head>

    <body>

        @TwitterGoodies.Search(searchQuery: "sitepointdotcom")

    </body>

</html>

And here are the search results.

fig15

Bing

The Bing web helper gives you the power to add a Bing search to your website. If you wanted to give users the ability to search on the Microsoft website from your website, add the following code:

@Bing.SearchBox("http://www.microsoft.com")

fig16

You also have the option of displaying advanced search options by using the AdvancedSearchBox method:

@Bing.AdvancedSearchBox(

    siteUrl: "http://www.asp.net",

    siteName: "ASP.NET",

    boxWidth: 200,

    resultWidth: 300,

    resultHeight: 300,

    themeColor: "Blue",

    locale: "en-AU"

)

By using optional parameters in .NET 4.0, I can specify one or all parameters for the AdvancedSearchBox method.  Searching for ASP.NET 4.0 displays the following results.

fig17

Chart

Charts are a great way to graphically represent data, and the Chart Web Helper makes it simple to add charts to your website. To render a chart, create a new page called PeopleChart.cshtml and add the following code:

<!DOCTYPE html>

<html lang="en">

    <head>

        <meta charset="utf-8" />

        <title></title>

    </head>

    <body>

        @{

        var key = new Chart(width: 600, height: 400)

            .AddTitle("Employees")

           .AddSeries(

           name: "Employee",

           chartType: "Pie",

           xValue: new[] {  "Peter", "Andrew", "Julie", "Mary", "Dave" },

           yValues: new[] { "2", "6", "4", "5", "3" })

           .Write();

     }

    </body>

</html>

The results are displayed in the pie chart below.

fig18

Setting the AddSeries xValue and yValue properties creates the data for the chart. The Write method renders the chart on the page. The chart looks good, but you may have noticed it takes up the whole page. That’s because by default the chart is rendered as a JPEG image. Normally, you’d want to render the chart inside an existing page; to do this, first create a new CSHTML page called PeopleChart.cshtml and add the Razor syntax to it:

@{

    var key = new Chart(width: 600, height: 400)

        .AddTitle("Employees")

        .AddSeries(

        name: "Employee",

        chartType: "Pie",

        xValue: new[] {  "Peter", "Andrew", "Julie", "Mary", "Dave" },

        yValues: new[] { "2", "6", "4", "5", "3" })

        .Write();

}

Now go back to the default.cshtml page and add an HTML image tag, but instead of referencing an image file, you need to reference the PeopleChart.cshtml page like:

<img src="@Href("~/chart.cshtml")" />

Now the chart is rendered along with the rest of the default.cshtml page.

Summary

In this article, I’ve taken you through some of the steps involved with creating dynamic content in WebMatrix. You’ve seen the slick new Razor view engine, as well as Razor syntax and integrating your website with social media giants Facebook and Twitter. WebMatrix does streamline development; I hope you’ve seen that in this article.

Next time, we’ll look more closely at how WebMatrix can help you publish your website. In the meantime, why not take our short quiz to check how much you’ve learned?

note:SitePoint Content Partner

This tutorial has been made possible by the support of Microsoft. In cooperation with Microsoft and independently written by SitePoint, we strive to work together to develop the content that’s most useful and relevant to you.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Kim Rossey

    Excellent post. Just wish something like WebMatric was introduced back in 2001. The jump from classic asp and vbscript to the .Net webforms world was too much for many. Not really in complication but a complete different way of doing web development with web forms. Many jumped ship. Anyway, WebMatrix is a huge positive and will give many a great tool to setup their first websites or sites that do not warrant a full blown Visual Studio solution.

  • Sandy

    I remember webmatrix back in 2003 when I first started to learn ASP.NET from classic VB6. I’m glad it’s still around.