Problem
How to share common visual elements, code blocks, and directives in ASP.NET Core MVC.
Solution
In an empty project, amend Startup class to add services and middleware for MVC.
- public void ConfigureServices(
- IServiceCollection services)
- {
- services.AddScoped<IGreetingService, GreetingService>();
- services.AddMvc();
- }
-
- public void Configure(
- IApplicationBuilder app,
- IHostingEnvironment env)
- {
- app.UseMvc(routes =>
- {
- routes.MapRoute(
- name: "default",
- template: "{controller=Home}/{action=Index}/{id?}");
- });
- }
Add a service and model.
- public interface IGreetingService
- {
- string Greet(string firstname, string surname);
- }
-
- public class GreetingService : IGreetingService
- {
- public string Greet(string firstname, string surname)
- {
- return $"Hello {firstname} {surname}";
- }
- }
-
- public class UserViewModel
- {
- public string Firstname { get; set; }
- public string Surname { get; set; }
- }
Add a controller with action method returning ViewResult.
- public IActionResult Index()
- {
- var model = new UserViewModel
- {
- Firstname = "Tahir",
- Surname = "Naushad"
- };
- return View(model);
- }
Add _Layout.cshtml.
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>@ViewBag.Title</title>
- </head>
- <body>
- <div>
- <strong>I'm in Layout page</strong>
- @RenderBody()
- @RenderSection("footer", required: false)
- @if (IsSectionDefined("links"))
- {
- @RenderSection("links", required: false)
- }
- else
- {
- <em>No social media links supplied</em>
- }
- </div>
- </body>
- </html>
Add Index.cshtml.
- @model UserViewModel
- @{
- ViewBag.Title = "ASP.NET Core MVC";
- }
- <strong>I'm in View page</strong>
- <p>@Greeter.Greet(@Model.Firstname, @Model.Surname)</p>
- @section footer{
- <strong>I'm in footer section</strong>
- }
Add _ViewImports.cshtml.
- @using Fiver.Mvc.Layout.Models.Home
- @inject IGreetingService Greeter
Add _ViewStart.cshtml,
Discussion
ASP.NET Core MVC provides ways to reuse and share visual elements and common code between different Views. These are,
- Layout Page
- Start Page
- Imports Page.
Layout Page
These are used to share common visual elements in your pages and provide a consistent look and feel throughout your application. A layout page is added to the Views/Shared folder and is named (as a convention) _Layout.cshtml. There can be more than one layout pages in your application too.
Views have a Layout property through which they set the layout to use. The layout page is searched in Controller-specific folder and then in the shared folder. Layout page calls @RenderBodymethod to render the contents of a View.
Layout page can also use @RenderSection to decide where sections defined in Views will be placed. These sections can be required or optional. Views define the contents of a section using @sectionsyntax. Layout page can check if a section is defined in the View and acts accordingly using IsSectionDefined method on the View.
- @if (IsSectionDefined("links"))
- {
- @RenderSection("links", required: false)
- }
- else
- {
- <em>No social media links supplied</em>
- }
Import Page
As we discussed in Razor post, Views can use directives for a number of things, e.g. importing namespaces (@using), injecting dependencies (@inject), and declaring model type (@model). MVC provides an import page to declare directives common to one or more Views.
Import page is added usually in Views folder and is named _ViewImports.cshtml. It can also be added to other folders (e.g., Controller specific Views folder) however, in this case it will apply to views inside this folder (and its subfolders).
In case of multiple import pages, either the directives close to the Views are used (e.g. @model,@inject) or all are combined (@using, @addTagHelper).
Start Page
MVC provides a mechanism to run code common to all views using a start page. Start page run before every view, except for layout page and partial views.
Start page is added usually in Views folder and is named _ViewStart.cshtml. There can be multiple start pages, in which case, they will run in hierarchical order from root to subfolders.
Start page is often used to set the Layout page for all the Views in a folder.
Source Code
GitHub