Book Image

Instant Razor View Engine How-to

By : Abhimanyu Kumar Vatsa
Book Image

Instant Razor View Engine How-to

By: Abhimanyu Kumar Vatsa

Overview of this book

Razor View Engine is an advanced view engine from Microsoft. Razor View is one of the most popular view engines which doesn't require you to explicitly close the code block. This book will help you understand and configure RazorView in your system to create dynamic web pages. Instant Razor View Engine How-to will help you to make your application more MVC friendly with clean, lightweight code which is quicker and easier to understand compared to other view engines. Instant Razor View Engine How-to introduces you to methods to make your web application more MVC friendly. The book begins by detailing the anatomy of RazorView Syntax and configuring Razor View as well as creating a web application project which will also help you to select an appropriate programming language. The later section of the book goes on to discuss creating view templates and creating View pages using Razor syntax. By the end of the book, you will also be familiar with Razor directives, helper components, and work with Partial views to reuse razor code throughout the application.
Table of Contents (7 chapters)

Razor layout pages (Become an expert)


In this recipe I will introduce you to Razor layout pages, and then we can move forward to cover every single Razor syntax existing in a layout page.

In a web application, it is very important to have content that is displayed on every web page. It may be a header, footer, menus, and so on. It saves a lot of work and centralizes the markup, style, and code which are easier to maintain.

In ASP.NET 2.0, the master page concept was introduced to help bring a content block from another file on a web page to DRY (Don't Repeat Yourself) and to give the web application a consistent look.

In ASP.NET MVC, Razor supports the concept of a layout page, which is similar to a master page. A layout page allows us to define a common website template. Let's learn more about the layout page.

Getting ready

In the Creating the project (Should know) recipe, we created a project using the Internet Application template and the Razor view engine. Open that project and read on reading further.

How to do it...

Before learning Razor layout pages, you should be aware of the _ViewStart.cshtml page. So, first we will look at the _ViewStart.cshtml page and then we will look at the layout page.

  1. With the release of ASP.NET MVC 3 Beta, we can now add a file called _ViewStart.cshtml (if the programming language is C#) or _ViewStart.vbhtml (if the programming language is VB) underneath the \Views folder of the ASP.NET MVC projects, which contains the information about the layout page.

  2. This _ViewStart.cshtml file can be used to define a common view code that you need to execute at the start of each view; we no longer need to explicitly set the layout in any of our individual view files except if we wanted to override the default value. If you open this file, you will see the following code snippet:

    @{
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
  3. I could write Layout = "~/Views/Shared/_Layout.cshtml"; on each view page in the project, but it is not DRY.

  4. What DRY does here is it writes Layout = "~/Views/Shared/_Layout.cshtml"; in the _ViewStart.cshtml file. Now, open the _ViewStart.cshtml file; the layout filename which is _Layout.cshtml by default could be anything else.

  5. We could write the code within the _ViewStart.cshtml file to programmatically set the Layout property for all views. Depending on the type of device that is accessing the site we can have a phone or tablet to optimize the layout for those devices, and a desktop to optimize the layout for PCs/laptops.

  6. Also, what if one wants to apply a new layout to all view pages inside the Demo folder? To do this, we could put a _ViewStart.cshtml file inside the /Views/Demo folder, which would override the default one in the /Views folder and specify the desired layout as shown in the following screenshot:

  7. If we write Layout = null; in the preceding code, it will stop applying any layout to all view pages inside the \Views\Demo folder and you will see a layout-free web page. In the case where you don't want any layout, this will work for you.

  8. When returning the view inside the controller, we could also specify which layout should be used, the following is an example:

    return View("Index", "~/Views/Shared/_LayoutName.cshtml", someViewModel);

That's all we need to cover about the _ViewStart.cshtml page.

Moving ahead, open the _Layout.cshtml file, which can be found in the /Views/Shared folder, and have a look at the code; it is shown in the following screenshot:

If you recall, I created this project using the Internet Application template in the Creating the project (Should know) recipe. This is why we have a ready-to-use layout which has <head> and <body> sections. In the <head> section, we have the title, links, meta, styles, and scripts, and in the <body> section we have the site title, menu, login, and so on, which makes a common layout that we can be used to maintain a consistent look and feel across any number of pages on our site.

Don't get confused with the amount of code in the preceding screenshot, they are pretty simple to understand. I'll discuss what each piece of code means, one by one, in a bit. Some of them will be discussed in the next recipe.

RenderBody(), which is a Razor syntax, is equivalent to ContentPlaceHolder, which is an ASPX syntax. In this code, we are calling the RenderBody() method within the layout file to indicate where we want the views based on this layout to "fill in" their core content at that location in the HTML. The following screenshot gives us an explanation:

Here, View Page 1 is just like the About.cshtml view page, and View Page 2 is like the Contact.cshtml view page, and so on. In the About.cshtml or Contact.cshtml view page, we do not need to wrap our main body content within a tag or element; by default Razor will automatically treat the content as the body section of the layout page. We can optionally define named sections if our layout has multiple replaceable regions; you will learn it in this recipe.

ViewBag.Title is used to output the View.Title property within the <title> element of our <head> section, shown in the following screenshot:

To understand this, open any view page; you will notice the ViewBag.Title property is assigned with a value, in this case we have Index, and now our <title> will become Index - My ASP.NET MVC Application:

ViewBag is a very well-known way to pass the data from controller to view and even from view to view. ViewBag uses the dynamic feature that was added in C# 4.0. In the preceding screenshot, we are programmatically setting the ViewBag.Title value within our Index.cshtml page. The code within our Index.cshtml file will run before the _Layout.cshtml code runs and so we can write the view code that programmatically sets values we want to pass to our layout to render. This is particularly useful for things such as setting the page's title, as well as <meta> elements within the <head> for SEO.


The System.Web.Optimization namespace has two awesome helpers, @Styles.Render and @Scripts.Render, which help us to perform Bundling and Minification. Minimizing the number of requests the page has to perform can have a considerable effect on our site's performance. Bundling and Minification are very common scenarios that help to reduce the number of requests and file size by bundling (that is, all CSS and JS files into two separate files) and minifying (that is, removing blank spaces that are not required, removing comments, and reducing identifiers).

Bundling and Minification is performed at runtime, so that the process can identify the user agent (for example IE, Mozilla, and so on), and thus improve the compression by targeting the user browser (for instance, removing stuff that is Mozilla-specific when the request comes from IE).

The code in the preceding screenshot actually calls the files included in that particular bundle, which is declared inside the BundleConfig class in the App_Start folder. Open this file, it should be as follows:

In that particular case the call to @Styles.Render("~/Content/css") is made to call "~/Content/site.css".

As we know, layouts in Razor serve the same purpose as master pages do in Web Forms. They allow you to specify a layout for your site and create a placeholder for your views to implement. Open the _Layout.cshtml file, you will see a section called featured, which is an optional section just above @RenderBody(), highlighted in the following screenshot:

Now, on any view page, if I want a featured section to appear, I could write following:

Using Razor, we can also check the existence of a section on a view page (Index.cshtml) from the layout (_Layout.cshtml) page, and depending upon its existence, we can display the alternative information.

In the following example, using the IsSectionDefined() method, we can check if the section has been defined on the view page or not. If it is not defined, the alternative information will be rendered.

On the Index.cshtml view page, I would not like the featured section to appear, so I'll not write it and Razor will display Alternative Information, as shown in the following screenshot:

Razor layout pages are equivalent to master pages in ASP.NET Web Forms. Just as it is possible to nest master pages, it is also possible to nest Razor layout pages.

To tryout an example of a nested layout page, create a new project with the Empty Project template. Please don't mix it in the project that we already have in place.

Consider a web application that has header and footer sections. The footer section will be visible to all but I would the like header section to be invisible to the admins. I would like to define a nested layout to enable this feature.

  1. Create a file in Views/Shared/_Layout.cshtml and write the following code in it. This is a top-level layout but looks like a regular Razor layout.

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <title>@ViewBag.Title</title>
        </head>
        <body>
            @RenderSection("header", required: false)
            @RenderBody()
            @RenderSection("footer", required: false)       
        </body>
    </html>
  2. Now, let's create a public-specific layout file in Views/Shared/_PublicLayout.cshtml and write the following code:

    @{
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <p>Hello from Public layout.</p>
    
    @section header{
        <p>
            header information goes here.
        </p>
    }
    
    @RenderBody()
    
    @section footer{
        <p>
            footer information goes here.
        </p>
    }

    In this code, first I defined which layout page this layout will inherit, and then I defined both the header and footer sections, including a RenderBody() call.

  3. Now, let's create an admin-specific layout file in Views/Shared/_AdminLayout.cshtml and write the following code:

    @{
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <p>Hello from Admin layout.</p>
    
    @RenderBody()
    
    @section footer{
        <p>
            footer information goes here.
        </p>
    }

    In this code, first I defined which layout page this layout will inherit and then I defined only the footer section and a RenderBody() call.

We are all set to test nested layouts. To test the public layout, add a view as given in the following screenshot and look at the output. Remember to point to the _PublicLayout.cshtml layout when adding any public view.

To test the admin layout, add a view as given in the following screenshot and look at the output:

You must have noticed that we can't see the header information goes here message in the admin layout. I hope you get the idea of using nested layouts.

How it works...

Razor is flexible enough so that we can make changes like the ones we saw in this recipe, without having to modify any of our view templates (nor make any controller logic changes) to accommodate this. We can instead make minimal modifications to our layout file and the rest happens cleanly. This type of flexibility makes Razor incredibly powerful and productive.

There's more...

The design (look and feel) of the ASP.NET MVC application is completely dependent on the _Layout.cshtml and Site.css files. So, to get a new look and feel, you have to update these files.