(C# ASP.NET Core) Partial Views from a Practical Perspective

So this article starts by explaining the various aspects of a partial view from a practical, day-to-day perspective. We have totally removed those parts that are either redundant or too complicated to be of any use for a practical developer. Then we take a small 3-step walkthrough that shows how to create a partial view, and how to consume it in a razor page. We also explain how a conditional menu can be conveniently implemented using the ideas of partial views. Partial Views + Razor Components can add to the confusion of a developer, so we finally conclude with a comparison with razor components.
(Rev. 19-Mar-2024)

Categories | About |     |  

Parveen,

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.