Reuse UI with Partial Views in ASP.NET Core MVC and Razor Pages

While developing ASP.NET Core web applications you often need to reuse parts of the user interface across many view or razor pages. There are multiple options to address this requirement simplest being Partial Views. In this article you will learn what partial views are and how to use them in ASP.NET Core MVC and Razor Pages applications.

Partials views are .cshtml files that house user interface elements such as HTML markup tags, tag helpers and razor code. Once created you can use the partial views on main views and razor pages of the application. By convention partial page names begin with an underscore (for example, _Partial1.cshtml). For ASP.NET Core MVC applications they are typically stored under Views/<Controller> or Views/Shared folder. For ASP.NET Core Razor Pages they are typically stored under Pages, Pages/<CallingPageFolder> or Pages/Shared folder.

Now that you know what partial views are, let's create one and then use it in an ASP.NET Core MVC application.

Create and setup a new ASP.NET Core MVC application. Add Shared subfolder under the Views folder and add a partial view named _CountriesPartial.cshtml into it.

The _CountriesPartial will render a list of countries as shown below:

@foreach(var item in Model)
{
    <h2>@item</h2>
}

Notice that the foreach loop uses Model property. By default, partial views get access to the view's model. Here, Model refers to the Index views model. This model is generated in the HomeController as follows:

public IActionResult Index()
{
    List<string> countries = new List<string>();
    countries.Add("USA");
    countries.Add("UK");
    countries.Add("India");

    return View(countries);
}

As you can see, the Index() action creates a List<string> containing a few countries. The List<string> then goes to the Index view as its model. Since _CountriesPartial is housed inside the Index view (discussed soon), the same Model is available to _CountriesPartial also.

Now that you have _CountriesPartial ready (see the Solution Explorer below) it's time to use it in the Index view.

There are various ways to render the content of _CountriesPartial onto a view. They are listed below:

  • Use <partial> Tag Helper
  • Use Html.Partial() HTML helper
  • Use Html.PartialAsync() helper
  • Use Html.RenderPartial() method
  • Use Html.RenderPartialAsync() method

The <partial> Tag Helper uses tag oriented syntax to indicate the location where the content of a partial view is outputted. The following markup shows how it can be used:

<partial name="_CountriesPartial" />

The Partial() and PartialAsync() HTML helpers are quite similar in that they accept the name of the partial view to be rendered. As you might have guessed the PartialAsync() helper does so in asynchronous manner. The following code shows how these helpers can be used.

@Html.Partial("_CountriesPartial")

@await Html.PartialAsync("_CountriesPartial")

The RenderPartial() and RenderPartialAsync() methods write the content of the partial view directly on the response stream. The Partial() and PartialAsync() return a string containing the response content of the partial view whereas RenderPartial() and RenderPartialAsync() return void. The following code shows how these methods can be used.

@{
    Html.RenderPartial("_CountriesPartial");
}


@{
    await Html.RenderPartialAsync("_CountriesPartial");
}

Notice they these methods must be called inside a razor code block since they are void methods.

The following figure shows a sample run of the application.

Using Partial Views in Razor Pages

The use of partial views in razor pages is quite similar to MVC application. However, there a few differences. Firstly, the partial views are typically located inside the Pages folder. 

For example, here we store _CountriesPartial.cshtml inside the Shared subfolder of Pages folder. The Index razor page can then house the partial view using the same techniques discussed earlier.

The following code shows how the List<string> containing a few countries is generated in the Page Model class.

public class IndexModel : PageModel
{

    public List<string> Countries { get; set; }

    public void OnGet()
    {
        Countries = new List<string>();
        Countries.Add("USA");
        Countries.Add("UK");
        Countries.Add("India");
    }
}

Notice that the OnGet() page handler create a List<string> as required and assigns it to the Countries page model property.

The _CountriesPartial.cshtml can render the country list as follows:

@foreach(var item in Model.Countries)
{
    <h2>@item</h2>
}

Since counties are expose through the Countries page model property, the foreach loop accesses them using the Model.Countries property.

The _CountriesPartial.cshtml can be used on the Index partial page just like the MVC example discussed earlier. The following code shows how the <partial> Tag Helper can do the job for us.

@page
@model PartialsDemo.Pages.IndexModel

<partial name="_CountriesPartial" />

Specifying model for the partial view explicitly

In the preceding examples the partial view implicitly got access to the main view's model or page model. However, you can explicitly pass model to the partial view. Consider the following Index() action.

public IActionResult Index()
{
    List<string> countries = new List<string>();
    countries.Add("USA");
    countries.Add("UK");
    countries.Add("India");
    ViewBag.Countries = countries;
    return View();
}

Here, the List<string> is stored in ViewData rather than passing to the Index view directly. Then the Index view can explicitly pass this List<string> to the _CountriesPartial as shown below:

<partial name="_CountriesPartial" 
model='ViewData["Countries"]' />

@Html.Partial("_CountriesPartial",ViewData["Countries"])

As you can see, the <partial> Tag Helper now uses the model attribute to supply the model to the _CountriesPartial.cshtml. Similarly, the Partial() HTML helper supplies the model via the second parameter.

You can accomplish the same thing in razor pages like this:

<partial name="_CountriesPartial" model="Model.Countries" />

@Html.Partial("_CountriesPartial",Model.Countries)

Here, the model is supplied using the Countries page model property. Since the model is supplied explicitly the _CountriesPartial needs to be changed accordingly:

@foreach(var item in Model)
{
    <h2>@item</h2>
}

Notice that now the partial view simply uses Model property (rather than Model.Countries) to access the Listt<string>.

Strongly typed partial views

You can also create strongly typed partial views using the @model directive and get all the benefits of strongly typed views such as IntelliSense and design time error checking.

@model List<string>

@foreach(var item in Model)
{
    <h2>@item</h2>
}

That's it for now! Keep coding!!


Bipin Joshi is an independent software consultant, trainer, author, and meditation teacher. He has been programming, meditating, and teaching for 24+ years. He conducts instructor-led online training courses in ASP.NET family of technologies for individuals and small groups. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get article updates : Facebook  Twitter  LinkedIn

Posted On : 22 April 2019


Tags : ASP.NET ASP.NET Core MVC C# Visual Studio


Subscribe to our newsletter

Get monthly email updates about new articles, tutorials, code samples, and how-tos getting added to our knowledge base.

  

Receive Weekly Updates