In the last module we installed the DotNet Libman tool and the Bootstrap package so that we can use Bootstrap in the layout.
In this module we are going to create the Layout template and configure the Razor View system.
Create the Layout Template
In the Views folder, create a new folder called Shared. Right click on the new Shared folder and select Add -> New Item...
.

In the Add New Item dialogue, search for Layout in the upper right textbox. Leave the filename as _Layout.cshtml, and click the Add button.

A new Razor file is created in the Views/Shared folder called _Layout.cshtml. Recall Razor Views have a .cshtml extension so this is a Razor View but a special kind. It will serve as a template for all the web pages we build so we don’t have to repeat the HTML code for all of the common areas over and over again like the header, footer and in some sites a top menu or side menu.
Here is the code automatically generated for the _Layout.cshtml file.
FredsCars/Views/Shared/Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
This looks very similar to the bare-bones structure of an HTML document we looked at in the “HTML Tags and Elements Explained” section in Chapter 1, Module 3.
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>
The Layout template in _Layout.cshtml will provide this bare-bones html structure to all of our web pages plus any common areas I talked about above, links to CSS or JavaScript files, and any common Razor or C# code, statements, and logic.
The RenderBody()
statement is where our web pages like the Index.cshtml ViewResult from the Home Controller will be embedded into the template.
@RenderBody()
Modify the _Layout.cshtml file with the code below.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Fred's Cars - @ViewBag.Title</title>
<link href="~/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<header>
Fred's Cars, Trucks & Jeeps
</header>
<div>
@RenderBody()
</div>
<footer>
Contact us: (555)555-5555<br />
121 Fredway St.<br />
Cartown USA
</footer>
</body>
</html>
In the code above we inserted a link to the Bootstrap CSS file along with Header and Footer elements.
Configure the Razor View System.
If we restart the application and browse to our website, the results will be the same. No header or footer is being inserted into the HTML. Also no Bootstrap is being applied. We still have the default font of the browser. This is because we need to configure the Razor View engine and the Layout System to work.
Create _ViewStart.cshtml
Right click on the Views folder and select Add -> New Item...
.
In the Add New Item dialogue, search for View Start, leave the filename as _ViewStart.cshtml and click the Add button.

The _ViewStart.cshtml file is added to the project and the code is autogenerated. The project structure should now look like the following.

And here is the autogenerated code.
FredsCars/Views/_ViewStart.cshtml
@{
Layout = "_Layout";
}
The ViewStart.cshtml file contains common code and logic that gets run for all views in the application. Basically, this code is setting _Layout.cshtml as the default layout template.
The ‘@’ sign in the above code is used in Razor to transition from HTML to C# or Razor specific markup when it is followed by a Razor-specific keyword. The ‘@’ sign followed by the two squiggly chars, ‘{}
‘ transitions from HTML into C#.
The two squigglies signify a C# block of code.
@{
// C# code
// Set the path of the layout page
Layout = "_Layout";
}
Now if you restart the application, your browser should look similar to the following.

We know the Layout file is now being used because the Header and Footer elements are being pulled in.
Also in the browser window if you hit the F12 key to open the web development tools (or right click in the browser and select inspect), click the Network tab, and then refresh the browser, you will see that after the browser makes an HTTP request to localhost:40443, our default route, it then makes a call to the Bootstrap file. The Status of both is 200 (OK) meaning both requests succeeded. So we also know the Index view is using the Layout View as a template because of the request to the bootstrap file.


Custom CSS with site.css
At this point, the application is using the Layout template view, but the header, content div, and footer elements are all crammed together. And we need to dress up the header and footer to make them look nicer. Do these problems seem familiar from Chapter 1?
Create the site.css file
Create a folder in the wwwroot folder called css.
Right click on the css folder and select Add -> New Item...
.
Search for css. Select Style Sheet in the results, and change the filename to site.css

Your project structure should now look like the following.

Add the site.css link to the Layout View
FredsCars/Views/Shared/_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-ixwidth" />
<title>Fred's Cars - @ViewBag.Title</title>
<link href="~/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<!-- ... -->
Customize the header and footer CSS
Add the code below to the site.css file.
FredsCars/wwwroot/css/site.css
body {
/* Sticky footer properties*/
display: flex;
flex-direction: column;
min-height: 100vh;
}
/* For sticky footer*/
.spacer {
flex: 1;
}
header {
padding: 5px;
background-color: black;
color: white;
text-align: center;
font-size: 16pt;
font-weight: bold;
font-family: arial;
}
footer {
background-color: black;
color: white;
text-align: center;
}
Restart the application and refresh your browser. The results should look like the screenshot below.

Recall in Chapter 1 we learned how to create a sticky footer and we are using the flex system in the same way here to accomplish that task. For a review of the sticky footer set up refer to the “Footer” and “Make that footer sticky” sections in Chapter 1, Module 3, “Mock your site with HTML”.
Create the Content Container
Modify the code in the Index View in the Views/Home folder.
FredsCars/Views/Home/Index.cshtml
<div class="container-fluid my-4 text-center">
<h1>Welcome to Fred's Cars!</h1>
Where you'll always find the right car, truck, or jeep.<br />
Thank you for visiting our site!
</div>
In the code above, we wrapped our welcome message and content in a div element containing the Bootstrap container-fluid
class and centered the text.
Restart the application and the results should look similar to the screenshot below.

Notice as you start typing in Visual Studio, you get a popup of options when typing in bootstrap styles. You can select the current highlighted style by hitting the TAB key or double clicking it.

This is called IntelliSense. And you will also be able to take advantage of this feature while writing C#.
Real Estate Placeholders
As in Chapter 1, we are going to put our Category Search Buttons on the left side and Search Results on the right side. Let’s set that up now.
Modify the Index View for the Home Controller with the code below.
FredsCars/Views/Home/Index.cshtml
<div class="container-fluid my-4 text-center">
<h1>Welcome to Fred's Cars!</h1>
Where you'll always find the right car, truck, or jeep.<br />
Thank you for visiting our site!
<div class="container-fluid mx-0 row"
style="margin-top: 20px;">
<div class="col-4" style="border-right: 2px solid black">
<h3>Categories</h3>
</div>
<div class="col">
<h3>Results</h3>
</div>
</div>
</div>
Configure Tag Helpers
While we are here, there is one last bit of configuration we need to do and that is to configure the built-in tag helpers.
Right click the Views folder and select Add -> New Item...
.
In the New Item dialogue, search for View Imports, select the Razor View Imports result in the middle pane, leave the filename as _ViewImports.cshtml, and click the Add button.

Your project structure should look like the following screenshot.

Modify the _ViewImports.cshtml file with the following code.
FredsCars/Views/_ViewImports.cshtml
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
The code above is saying to enable access to all of the built-in tag helpers within the Microsoft.AspNetCore.Mvc.TagHelpers
namespace.
Tag helpers are a feature of ASP.NET Core that allow developers to add dynamic behavior to web pages by creating and rendering HTML elements in Razor files.
Tag helpers are written in C# and target HTML elements based on their name, attribute name, or parent tag.
Let’s take a look at an example of a Tag Helper in the next section.
The Anchor Tag Helper
Modify the Index View for the Home Controller with the code below.
FredsCars/Views/Home/Index.cshtml
<div class="container-fluid my-4 text-center">
<h1>Welcome to Fred's Cars!</h1>
Where you'll always find the right car, truck, or jeep.<br />
Thank you for visiting our site!
<div class="container-fluid mx-0 row"
style="margin-top: 20px;">
<!-- Categories -->
<div class="col-4 col-md-3 col-lg-2"
style="border-right: 2px solid black">
<div class="d-grid gap-2 button-grid">
<a asp-controller="Vehicle"
asp-action="Index"
class="btn btn-primary button">
<b>ALL</b></a>
<a asp-controller="Vehicle"
asp-action="Index"
class="btn btn-outline-primary button">
<b>CARS</b></a>
<a asp-controller="Vehicle"
asp-action="Index"
class="btn btn-outline-primary button">
<b>TRUCKS</b></a>
<a asp-controller="Vehicle"
asp-action="Index"
class="btn btn-outline-primary button">
<b>JEEPS</b>
</a>
</div>
</div>
<!-- Results -->
<div class="col">
<h3>Results</h3>
</div>
</div>
</div>
Next, modify the site.css file with the code below.
FredsCars/wwwroot/css/site.css
header {
padding: 5px;
background-color: black;
color: white;
text-align: center;
font-size: 16pt;
font-weight: bold;
font-family: arial;
}
footer {
background-color: black;
color: white;
text-align: center;
}
.button{
width: 100px;
}
.button-grid {
float: right;
}
In the above code we used the built-in Anchor Tag Helper to create the Category Search buttons. As an example, let’s look at the CARS anchor button code.
<a asp-controller="Vehicle"
asp-action="Index"
class="btn btn-outline-primary button">
<b>CARS</b></a>
Also notice in Visual Studio, Tag Helper HTML element names and properties have a special purple font.

At this point, if you restart the application your browser should look similar to the screenshot below.

Right click on the CARS button in the browser and click inspect to open the web developer tools and hone in on the CARS anchor element tag helper.


In the screenshot above, you can see in the web development tools that the anchor Tag Helper was converted to HTML based on its asp-controller
and asp-action
properties.
<a class="btn btn-outline-primary button"
href="/Vehicle">
<b>CARS</b>
</a>
These two C# Tag Helper properties were converted to an HTML anchor element’s href property.
The href property points to the Vehicle Controller in the first segment of the URL. And it doesn’t need a second segment for the Index action because that is the default action of the default route in Program.cs
We will see other built-in Tag Helpers along the way. For instance, we will see input tag helpers, label tag helpers, and validation tag helpers to help validate input in forms.
ViewBag: Setting the browser title
Let’s take a look back at the Layout file and inspect the title tag.
<title>Fred's Cars - @ViewBag.Title</title>
The title of the browser is set to the static literal string, “Fred’s Cars – “, followed by the dynamic value of the ViewBag’s Title property.
The ViewBag in ASP.Net Core MVC is a C# dynamic dictionary meaning we can add any property we want to it on the fly.
The ViewBag’s Title property gets set by any Razor View using the Layout file. In our case, currently the only Razor View using it is the Index View of the Home Controller.
Modify the Index View of the Home Controller with the following code.
FredsCars/Views/Home/Index.cshtml
@{
ViewData["Title"] = "Welcome";
}
<div class="container-fluid my-4 text-center">
<h1>Welcome to Fred's Cars!</h1>
Where you'll always find the right car, truck, or jeep.<br />
Thank you for visiting our site!
<div class="container-fluid mx-0 row"
style="margin-top: 20px;">
<!-- Categories -->
<div class="col-4 col-md-3 col-lg-2"
style="border-right: 2px solid black">
<div class="d-grid gap-2 button-grid">
<a asp-controller="Vehicle"
asp-action="Index"
class="btn btn-primary button">
<b>ALL</b></a>
<a asp-controller="Vehicle"
asp-action="Index"
class="btn btn-outline-primary button">
<b>CARS</b></a>
<a asp-controller="Vehicle"
asp-action="Index"
class="btn btn-outline-primary button">
<b>TRUCKS</b></a>
<a asp-controller="Vehicle"
asp-action="Index"
class="btn btn-outline-primary button">
<b>JEEPS</b>
</a>
</div>
</div>
<!-- Results -->
<div class="col">
<h3>Results</h3>
</div>
</div>
</div>
Restart the application, refresh your browser, and the result should look similar to the following screenshot.

Bootstrap & CSS tips and tricks.
In Chapter 1 we learned a little about CSS and Bootstrap. But I wanted to keep things very simple at that point. In this module I have improved the responsiveness of the left side category buttons section to adjust how much space it takes up (or how many columns in the 12 column Bootstrap grid system) depending on the width of the screen.
Using Bootstrap Breakpoints
Originally, we had the Categories column div element always taking up 4 column spaces out of the 12 column Bootstrap Grid layout system.
<!-- Categories -->
<div class="col-4
style="border-right: 2px solid black">
<!-- Buttons -->
</div>
Because we do not explicitly express the amount of columns spaces the results column div element takes up, it automatically adjusts itself to the eight left over column spaces out of 12.
<!-- Results -->
<div class="col">
<h3>Results</h3>
</div>
The problem: static column spacing
The problem here is that once the browser screen hits a width of 768 pixels wide, there is just too much space in the Categories column. Too much space is wasted for the results column to use.
Screen width at 768 pixels wide

And it gets even worse at 992 pixels wide.
Screen width at 992 pixels wide

The solution: Bootstrap breakpoints
The solution was to add Bootstrap breakpoints to the Bootstrap col-* styles (where * is the number of columns to take up).
<div class="col-4 col-md-3 col-lg-2"
style="border-right: 2px solid black">
<!-- buttons -->
</div>
Now, with the browser at the smallest width possible, the categories div will start out taking up 4 out of 12 spaces. But as soon as the browser window is stretched to 768 pixels (the Bootstrap Medium breakpoint), the categories div will take up only 3 columns out of 12. It will remain taking up 3 columns out of 12 until it is stretched to 992 pixels (the Bootstrap Large breakpoint) and then only take up 2 columns out of 12 no matter how much more the window gets stretched in width.
browser window at 400 pixels wide

browser window at 768 pixels wide

browser window at 992 pixels wide

Bootstrap Breakpoints review
To review, here is a complete list of Bootstrap breakpoints.
Breakpoint | Class infix | Dimensions |
---|---|---|
X-Small | None | <576px |
Small | sm | ≥576px |
Medium | md | ≥768px |
Large | lg | ≥992px |
Extra large | xl | ≥1200px |
Extra extra large | xxl | ≥1400px |
You can read more about Bootstrap breakpoints here.
Right align & spacing of Category Buttons
The responsiveness of the category buttons is much improved but it would look even better if the Category buttons were right aligned.
browser window at 1685 pixels wide

To achieve this I first nested the Category buttons in their own div element within the parent Categories column div element.
<!-- Categories -->
<div class="col-4 col-md-3 col-lg-2"
style="border-right: 2px solid black">
<div class="d-grid gap-2 button-grid">
<!-- buttons -->
</div>
</div>
In Chapter 1, in order to get some vertical spacing between the buttons, we put each button in its own div element and add custom margin styling in the style element.
Here, we use the Bootstrap d-grid
and gap-2
styles to achieve the same result with less code. And by using Bootstrap styles we are ensured of a consistent look and feel across all modern browsers.
In order to right align the nested Category buttons div element within the parent Categories column div element, I added a custom button-grid class and gave it the float: right
style in site.css.
.button-grid {
float: right;
}
browser window at 1700 pixels wide. Buttons right aligned in their parent div element.

What’s Next
Now that we have the Razor View Engine and Layout System configured, and we have a controller and a view, we can move on to the most important component of MVC; The model.
In the next module, we are going to start modeling our domain with C# objects. We are also going to start learning about Entity Framework and Data Migrations.