When do you need a Partial View?
There are some subtle differences between a partial view and a razor component. We discuss that towards the end of this article.One line answer: consistency of layout of a model. For example, your project has to render a product at various places, and you would want a consistent html everywhere. Then, instead of repeating/copy-pasting the same html, you can consider creating a partial view for the product, and insert that partial view wherever you want the product rendered.
Partial views make code maintenance easier. The html mark-up can be changed just at one place (in the partial view), and the entire project will see those changes implemented.
"Shared" folder and Partial Views
Practically speaking, you should add your partial views to a folder called Shared
. This folder can be (i) directly in the root of your website (ii) can be in the same directory as your razor pages. The thumb rule is to place a partial view in the Shared
folder closest to the outermost razor page that uses it. So, if a partial view is used by many pages of various Areas
, then it is suggested that it should be in the Shared
folder of the root directory.
Naming of Partial Views
File extension of partial views is .cshtml
The convention is to start the name with an underscore followed by a capital (uppercase) letter. Camel (pascal) notation is recommended. So a partial page can be named _Product.cshtml
,
How is a Partial View Rendered?
The most practical and optimal way is to the use the tagHelper called partial
and set two attributes - (1) name
and (2) model
.
The name
attribute: Practically speaking, if your partial view is in one of the "Shared" folders then set the name attribute to the name of the partial view without its file extension. Optionally, you can write the full relative path to your partial view including the file extension.
// just the name of the file if the file // is in one of the "Shared" folders // ASP.NET can discover it! <partial name="_Product" . . . /> // OR path + extension <partial name="/Pages/Shared/_Product.cshtml" . . . />
The model
attribute: set this attribute to the model instance like so:
// assuming prod // is an identifier that references // a product instance <partial model="prod" . . . /> // OR can be inlined <partial model="@(new Product() { set properties } )" . . . />
Video Explanation with a Working Example
Please watch the following youtube video:
Objective of this Walkthrough
To create a partial view for a model class and render it in a razor page using a foreach loop.
Step 1 of 3: Create a Model Class
(see the linked video for more details)
Create a simple ASP.NET Core application with just one razor page called Index.cshtml
Add a model class as shown below
// file is Product.cs // we recommend that this file be // placed in a folder called "Models" // class starts public class Product { // unique id public int ID { get; set; } // display name public String Name { get; set; } // cost public float Price { get; set; } }
Step 2 of 3: Create a Partial View
(see the linked video for more details)
Add a folder called Shared
, and right-click to add an empty file called _Product.cshtml
. This file is our partial view.
A partial view doesn't contain the @page
directive.
The partial view below contains an @model
directive to reference the type of data being passed to it.
Notice that ViewData
dictionary is accessible inside a partial view.
// NOTE: css not shown //reference to the model class // that we have written above @model Models.Product <div> <h3>@Model.Name</h3> <div> <p>Price: @Model.Price</p> <!-- ViewData dictionary is accessible to a partial view but not to a razor component because a partial view runs runs in the chain/flow/context of a page, whereas a razor component runs as standalone/independent --> @if (null != ViewData["disc"]) { <p>Discount Today: @ViewData["disc"]</p> } <p> <a href="/Cart/@Model.ID">Add to Cart</a> </p> </div> </div>
Step 3 of 3: Render the Partial View
(see the linked video for more details)
In the code below, a list/collection of Product
items is obtained in the @code
block. Usually this code runs in the OnGet method of the backing class. We have written it here only for sake of this tutorial.
// Index.cshtml razor page @page @using Models @{ // some database query in the OnGet of the // backing class gives a list of products // but written here for the sake of this tutorial var Products = new Product[] { new Product(){ ID = 0, Name = "Laptop", Price = 200f }, new Product(){ ID = 1, Name = "Phone", Price = 100f } }; // add something to ViewData dictionary ViewData["disc"] = "10% off today"; } <h1>Products Page</h1> @foreach (var product in Products) { <partial name="_Product" model="product" /> }
Use of Partial Views for Menu
(see the linked video for an example)
One of the best use-cases of partial views is to use them for writing a menu.
For this, write all the links + any css class attributes etc., in a partial view and render it at the place where you would want the menu appear - header, footer, sidebar.
Conditional statements along with a suitable @model
can be used to alter the menu.
Razor Components vs Partial Views?
Both generate HTML, and a clever developer can twist either of them into work.
Partial Views are "chained" into the flow of a page. ViewBag and HttpContext - for example - are accessible within a partial view, because partial page is a part of the chain. Behaviour of a partial page depends on the context, on the page of which it is a part.
Razor Components are "embeddable", iframe-like, units; they are independent, stand-alone, and of a consistent behaviour, even across projects. You cannot access ViewBag inside a razor component. You cannot access HttpContext either. As a workaround, if you are hard-pressed for that, then you can, however, pass discrete data and references, such as of HttpContext (!) as a parameter.
This Blog Post/Article "(C# ASP.NET Core) Partial Views from a Practical Perspective" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.