In any professional application, there are some common UI parts of the application which does not change throughout the application, or we can say these portions remain the same throughout the application, which actually gives the application a common look and feel.
For any application, a common look and feel is very important for its branding. For example, whenever we think of Facebook, our mind only thinks of two colors: Blue and White. This is because all the common elements of Facebook, such as its header, footer, and logo, are blue and white in color, which provides users with a pleasant experience. Actually, a human mind can only remember things that repeat themselves frequently. The same concept is applied in website or web application development: the more frequently used parts are kept the same throughout the application, so that the user becomes accustomed to them.
Now, you got the point why a common look and feel is important. The question arises as to how to give our application a consistent look and feel. There are two ways:
- Copy header, footer, and all other common UI parts on each page of your application. Or,
- Create a single page with the common UI parts and refer to it in the other pages of your application.
Obviously, the first solution is more time-consuming and increases duplicate codes, so it is not efficient. The second solution is time-saving, increases reusability, and supports faster development.
ASP.NET MVC Layout is just an implementation of the second solution. This means that all the common UI elements will be placed on the Layout page, and all other pages of your application that change dynamically will inherit from your Layout page. Refer to the diagram below for a better understanding.
It should be very clear from the above figure that all the child pages (view pages) will be merged with the Layout page at run time. Now, it is time to learn how to create a Layout in MVC and how child pages will inherit from this page.
To create a Layout page, right-click the Shared folder of your application and add Layout as shown below. As the Layout page is meant for reusability, the Shared folder is the best place to keep it.
Two important questions that need to be answered here are:
- How the Layout page is inherited from the view pages.
- What are RenderBody and RenderSection.
Let's try to answer one by one.
How the Layout page is inherited from the view pages.
The view page can be inherited from the Layout page in any of the following ways:
- Defining Layout's path in the _ViewStart page.
- Defining Layout's path in the View page.
- Defining Layout's path in the Action Method.
i). Defining Layout Path in the _ViewStart
In the ASP.NET MVC life cycle, ViewStart runs each time before rendering the actual view on the screen, and checks whether the path for Layout is specified or not. If it finds the path for the Layout, then that Layout becomes the Layout for the executing view and merges with the view.
The ViewStart can be used in two ways.
i) Global Level: The ViewStart, which resides at the bottom of the View folder, is considered the global ViewStart, and the Layout specified there becomes the default Layout for every view in your application. In other words, if no Layout is specified at the page or action level, this Layout will be used by default.
ii) Folder level: One can also create ViewStart at the folder level, meaning if you create ViewStart in the Supplier folder (Auto-generated to keep all views of Supplier controller ), then the specified Layout becomes the default Layout for all views within the Supplier folder.
While adding a view for any Action Method, if you have specified a Layout in the _ViewStart, then leave the Layout option as it is, meaning blank as shown in the figure below:
ii) Defining Layout path in the View Page
You can specify the Layout's path in the view page, which will override the Layout specified in the _ViewStart at run time with the syntax specified below:
@{
Layout = "~/Views/Shared/_MyLayout.cshtml";
}
iii) Defining Layout in the Action Method
You can also specify Layout in the Action Method as given below:
public ActionResult Index()
{
return View("Index","_MyLayout");
}
What does @RenderBody and @RenderSection do?
RenderBody
RenderBody can be considered as a placeholder for dynamic content (the child Views) inside a Layout view. Meaning, wherever you specify @RenderBody() in your Layout page, the dynamic content (View) will be merged at that exact place at runtime. Refer to the image below if you are unable to understand.
RenderSection
There are some sections of view which should be in Layout but are dynamic in nature and change per view, meaning they are different for different views, so they can't be kept in the Layout page directly. For example, the title of a site changes for every navigation, and each view has a different title. However, the title of a Page should always be defined in the head section. Similarly, each view may contain different CSS and Scripts, which are placed in the head and body tags of an HTML file, respectively. For such situations, we can create sections with specific names in the Layout Page, and each child page is bound to define those sections if the required property is set to true. At runtime, the sections will be merged at the appropriate place in the Layout where we specified the section, while the other part of the view will be merged at the place where RenderBody is defined.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
@RenderSection("Title", true)
@RenderSection("Style", false)
</head>
<body>
<div>
@RenderBody()
</div>
@RenderSection("Script", false)
</body>
</html>
It has two overloaded versions: one that only accepts the section name, and in that case, each view is bound to define that section; otherwise, it will give a runtime error.
@RenderSection("Title")
The other overloaded version accepts the Name and Required boolean parameters, which specify whether the section is mandatory or not.
@RenderSection("Style", false)
To define a section in the view page, we use the syntax below.
@section Title{
MyTitle
}
Difference between @RenderBody and @RenderSection
- A Layout can have only one RenderBody() but multiple RenderSection().
- RenderBody() doesn't have any parameter but RenderSection() have parameters.
- RenderBody() is compulsory in a Layout but RenderSection() is not.
- RenderBody() renders all the content of the view except that specified in the named section, but RenderSection() only renders its own content.