Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Various ways of using Shared Layout in ASP.NET MVC

0.00/5 (No votes)
1 Jun 2015 2  
In this article we will discuss about various ways of using shared layout page in ASP.NET MVC applications. To experience it practically we will create a demo application implementing those different ways to define layout page in ASP.NET MVC.

Introduction

In this article we will discuss about various ways of using shared layout page in ASP.NET MVC applications. To experience it practically we will create a demo application implementing those different ways to define layout page in ASP.NET MVC.

Pre-requisites

You should be at intermediate level with C#, ASP.NET MVC, jQuery and HTML to have a good time with this article. For beginners, Please learn basics of above technologies first and you can put comments below article in case of any query. I will be happy to answer your queries. Thanks.

Outlines of Article

  • Why Shared Layout Page
  • Overview of Demo Application
  • Using _ViewStart file and _Layout.cshtml (Default way): Home Module
  • Define Layout in ActionResult: Ladies Module
  • Define Layout in Content Page: Kids Module
  • Define Layout for a Directory: Gents Module
  • Define Layout for an Area: Electronics Module
  • Bonus Point: Why _Layout.cshtml start with underscore

Why Shared Layout Page

As we know, most of web applications have logo/branding features, navigation bars, header, footer and some section of advertising (optional) etc. And these things are common across website. Besides we should maintain consistent look and feel across all web pages. So better approach is to write code having above mentioned elements into a separate file called layout file and share this file with all other web pages. It which creates consistent look and feel. By writing shared code in a common layout file, we avoid repetition, save time and it is easier to change in one shot for all pages if needed. In other words, shared layout page introduces reusability and increases maintainability.

Overview of Demo Application

Demo application is divided into five modules and each module is following a specific way to render layout page which we will learn further in this article. To provide a quick idea of what we would be accomplishing at the end of code demo of this article, below is the look of finished application having links to all five demonstrations. In this demo, we will change layout page and the way it is getting rendered for each module. For example, if you will click on "Gents" menu, Layout page will change and it will be rendered using accordingly.

FinalOutput
Note: We assume you have downloaded the attached sample code having the running project. If not, please do so as we are not providing detail or screen shots for all code here.

Creating ASP.NET MVC 4 Application

Before starting, please note the following points while following the steps given to creating demo applications:

  1. We will use Visual Studio 2012 with ASP.NET MVC 4 to develop the demo so attached code will run perfectly without any change with same setup.
  2. We have tested the running application on Internet Explorer version 10 and Chrome version 38. Screenshots attached with this article are taken while running application in Chrome browser.
  3. You can use Visual Studio 2013 also with ASP.NET MVC 4 or 5 installed.
  4. If you are using older version of Visual Studio/ ASP.NET MVC then you need to create similar solution and be careful for small changes due to different version.

Now let’s open up Visual Studio and start building demo. Let us create a sample application by selecting ASP.NET MVC4 Web Application template and give it project name as LayoutDemo and click OK. Project would be created. In next section we will understand default setting for layout page and its working.

Project Template
 

Using _ViewStart file and _Layout.cshtml

Till ASP.NET MVC 2, we were not having _ViewStart file. To provide consistent layout, we had to specify path for Layout page in each View. If we were changing name of layout file or place of layout file, we had to modify all views/content pages in the application.

It was like duplication of same code in each view to apply common layout and hard to maintain in big application. So to cope up with this problem, Microsoft ASP.NET MVC team introduced a new file called _ ViewStart with ASP.NET MVC 3 with Razor engine. _ViewStart file is executed in the beginning of each view's rendering. In this file within a code block, path of layout page (_Layout.cshtml file) is defined. So by default, this file become responsible to set the layout page to be used by the views in the application.

Let us see how _ViewStart and _Layout files are used by default in our demo application. To render _Layout page for Home module, by default _Layout is placed in Shared folder and all views in Views folder will use same _Layout which is specified in _ViewStart (untill specified otherwise or overruled). For Home page of our demo application, _Layout page is rendered with the help of _ViewStart file. In this Home page, an image is used to make the header of home page, which is placed in images folder inside of Content folder.

To render images, we need to apply some style and to get some dynamic stuff. All required css is written in custom.css file and jQuery code is written in app.js file, some css and js files are used given by framework as shown below.

Scripts and Content

Let us create partial view called Menu and place it in shared folder. This partial view will be used further which is having code to create links for different modules. Below is code for this partial view:

<nav>
    <ul>
        <li>@Html.ActionLink("Home", "Index", "Home", new { area = "" }, null))</li>
        <li>@Html.ActionLink("Gents", "Index", "Gents", new { area = "" }, null))</li>
        <li>@Html.ActionLink("Ladies", "Index", "Ladies", new { area = "" }, null))</li>
        <li>@Html.ActionLink("Kids", "Index", "Kids", new { area = "" }, null))</li>
        <li>@Html.ActionLink("Electronics", "Index", "ElectronicsHome", new { area = "Electronics" }, null)</li>
    </ul>
</nav>
    

Modify existing _Layout.cshtml file as per our requirement.

        
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
 @*Bundling is used while referencing css and javascripts files*@    
    @Scripts.Render("~/bundles/jquery")   
    @Styles.Render("~/Content/css")     
</head>
<body>
    <div class="container">
        <heade>
            <img src="~/Content/images/header_image/header.jpg" />
           @Html.Partial("Menu")
        </header>
        <br />
        <br />
        <div id="pageContainer">
            @RenderBody()
        </div>
    </div>
</body>
</html>
    


In above code, bundling is used to refer various css and js files. If you are new to bundling and minification concept of ASP.NET MVC, please visit here. Below code is used to refer css and js files. Bundles are created in BundleConfig.cs file under App_Start folder.

@Scripts.Render("~/bundles/jquery")   
@Styles.Render("~/Content/css")  
    

Next we have used header image and then a partial view called Menu to create menu bar. Finally @RenderBody() method is used to render content of actual view that is Views/Home/Index.cshtml in our case here.

Define Layout in ActionResult

Now we will render Layout page from ActionResult. In this case you need to put your _Layout page either in shared folder or in any directory comes under Views folder.

To render different layout page for Ladies module, add a layout page to shared folder with _LadiesLayout name and write same code as shown below.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" /> 
   @Styles.Render("~/Content/css")
   @Scripts.Render("~/bundles/jquery")
    
</head>
<body>
    <div class="container">
        <header>           
              <ul class="bxslider">
                <li> <img src="../../Content/images/ladies_image/image1.jpg" alt="Slide" />
                <li> <img src="../../Content/images/ladies_image/image2.jpg" alt="Slide" /> 
                <li> <img src="../../Content/images/ladies_image/image3.jpg" alt="Slide" />
                <li> <img src="../../Content/images/ladies_image/image4.jpg" alt="Slide" />
                <li> <img src="../../Content/images/ladies_image/image5.jpg" alt="Slide" /> 
                <li> <img src="../../Content/images/ladies_image/image6.jpg" alt="Slide" />
                <li> <img src="../../Content/images/ladies_image/image7.jpg" alt="Slide" /> 
                <li> <img src="../../Content/images/ladies_image/image8.jpg" alt="Slide" /> 
                <li> <img src="../../Content/images/ladies_image/image9.jpg" alt="Slide" />
             </ul>           
           @Html.Partial("Menu")
        </header>
        <br />
        <br />
        <div id="pageContainer">
            @RenderBody()
        </div>
    </div>
   <script>
       $(window).load(function () {
           $('.container').find('img').each(function () {
               var imgClass = (this.width / this.height > 1) ? 'wide' : 'tall';
               $(this).addClass(imgClass);
           })
       })
       $('.bxslider').bxSlider({
           minSlides: 4,
           maxSlides: 50,
           slideWidth: 250,
           ticker: true,
           speed: 40000
       });
    </script>
</body>
</html>
    

As you can see, above code is similar to _Layout.cshtml file which we have used with Home module. Some images are referenced and couple on lines code is written in jQuery. In _LadiesLayout page we are going to render queue of images for showing ladies dresses. To render these images dynamically, we are using a jQuery plug-in called bxSlider from here. Those files are referenced in Bundel.config file. Here just we are controlling speed of moving images etc. by using bxSlider function which is written in that plug-in. Add a controller called LadiesController and write same code as written below.

 public class LadiesController : Controller
 {
      public ActionResult Index()
      {
        return View("Index", "_LadiesLayout");
      }
 }
    

This Index action method returns Index view and use _LadiesLayout page.

Define Layout in Content Page

To render different layout page for Kids module, we will give the reference of Layout page from content page. Add a layout page to shared folder with _KidsLayout.cshtml name and all code will be same as _LadiesLayout.cshtml. Only references of kid’s images will be changed. Now put the reference to kids images as shown below.

<header>           
    <ul class="bxslider">
        <li> <img src="../../Content/images/kids_image/image1.jpg" alt="Slide" /> 
        <li> <img src="../../Content/images/kids_image/image2.jpg" alt="Slide" /> 
        <li> <img src="../../Content/images/kids_image/image3.jpg" alt="Slide" />
        <li> <img src="../../Content/images/kids_image/image4.jpg" alt="Slide" /> 
        <li> <img src="../../Content/images/kids_image/image5.jpg" alt="Slide" /> 
        <li> <img src="../../Content/images/kids_image/image6.jpg" alt="Slide" /> 
        <li> <img src="../../Content/images/kids_image/image7.jpg" alt="Slide" /> 
        <li> <img src="../../Content/images/kids_image/image8.jpg" alt="Slide" /> 
        <li> <img src="../../Content/images/kids_image/image9.jpg" alt="Slide" /> 
     </ul>           
        @Html.Partial("Menu")
</header>
    

Add a controller called KidsController and write same code as written below.

public class KidsController : Controller
{
   public ActionResult Index()
   {
    return View();
   }
} 
    

Right click on Index action method to add a view with same name. Write following code in Index page.

@{
   Layout = "~/Views/Shared/_KidsLayout.cshtml";
}
<div id="commonInfoDiv">
<b>Kids: Kids module is returning (rendering) Layout by defining Layout in each view </b>
</div>
    

As you can see, we have given the path for _KidsLayout.cshtml layout page in the content view which we want to use for for a perticular View in Kids module. Now run the application, click on Kids module. You would be able to see the running images of kids image.

Define Layout for a directory

If you have some such kind of scenario where you want to apply some special kind of Layout page on some set of Views which are placed in a particular directory. In this case you need to add a _ViewStart.cshtm and your layout file in the same folder. To demonstarte that, add a controller called Gents, we will use this Gents controller for Gents module. In this controller, you will get Index action method. Right click on Index action method to add a view. This view will not have anything but simple text as:

<div id="commonInfoDiv">
    <b>Gents: Gents module is returning (rendering) Layout by adding _ViewStart and specific layout file in Gents directories </b>
</div>
    

Add a view with _ViewStart.cshtml name to Gents folder and write below line of code:

@{    
    Layout = "~/Views/Gents/_GentsLayout.cshtml";
 }
    

Add a layout page maned as _GentsLayout.cshtml in Gents folder. Code will be same as _LadiesLayout.cshtml, only reference for images will be changed.

<header>           
    <ul class="bxslider">
        <li> <img src="../../Content/images/gents_image/image1.jpg" alt="Slide" /> 
        <li> <img src="../../Content/images/gents_image/image2.jpg" alt="Slide" />
        <li> <img src="../../Content/images/gents_image/image3.jpg" alt="Slide" />
        <li> <img src="../../Content/images/gents_image/image4.jpg" alt="Slide" />
        <li> <img src="../../Content/images/gents_image/image5.jpg" alt="Slide" /> 
        <li> <img src="../../Content/images/gents_image/image6.jpg" alt="Slide" /> 
        <li> <img src="../../Content/images/gents_image/image7.jpg" alt="Slide" />
        <li> <img src="../../Content/images/gents_image/image8.jpg" alt="Slide" />             
     </ul>           
        @Html.Partial("Menu")
</header>
    

Run the application, click on Gents module, you should be able see to running gents dress images which you have referenced in _GentsLayout.cshtml file.

Define Layout for an Area

In this section we will see how to apply different layout in views comes under different Areas in ASP.NET MVC application. If you are new to the concept of Areas, please first have a look this article on Area. As I have already explained about Areas in detail there, I would go here in brief.

So add an area called Electronics to our demo application. Then add controller in Controller folder called ElectronicsHome, add a view to Views folder, _ElectronicsLayout to Shared folder and add _ViewStart file in Views folder. For routing, change code in ElectronicsAreaAreaRegistration.cs file too. Make sure to use same code in different files as it is written in downloaded code. After adding files in Electronics Areas folder structure look like as shown below.

Areas

Once done with modification, run demo application, click on Electronics module, you will get the desired output.

Why _Layout.cshtml start with underscore

Razor was developed for ASP.NET Web Pages(WebMatrix), which doesn't have the same sort of protection built in regarding Views folders and Routing that you get within ASP.NET MVC. Since layout pages in Web Pages are not intended to be served directly, they are prefixed with the underscore. And the Web Pages framework has been configured not to allow files with leading underscores in their names from being requested directly. Other .cshtml files within Web Pages generally need to be browsable.

The ASP.NET team have stated that Web Pages was a starting point, which may lead to migration to MVC in time. It means now that it should be as easy as possible to migrate from Web Pages to MVC. Consequently, it makes sense to carry over naming conventions established within Web Pages to MVC Razor files. So there is a technical reason for prefixing the file names with an underscore in WebMatrix but it just isn't relevant to MVC. [This is based on answer given by Mike Brind on Stackoverflow.]

Conclusion

In this article we understood various ways of defining layout page in ASP.NET Application. You are invited for discussion, please provide your sugessions and comments. Thanks.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here