Next .NET Core version 3.1 brings some good news to Blazor – partial page classes. Maybe it’s not so big thing for many guys out there but sure great feature for those who like clean solutions. Here’s my story about partial page classes and their comparison with code-behind classes supported already today.
Deafult weather forecast page
When we create new Blazor application there’s page for weather forecast (named as FetchData.razor). It uses ForecastService and Forecast classes to fetch data from server. Here is the code for forecast page.
@page "/fetchdata"
@using BlazorApp5.Data
@inject WeatherForecastService ForecastService
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from a service.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[] forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
}
}
Besided markup it also contains code to load weather forecasts.
Using partial class
It’s not different from how we use code-behind classes from what Blazor pages inherit. The only difference is in “partial” keyword and in Razor page we don’t have to add @inherits directive to specify code-behind class.
As we have now everything we need to separate code and presentation it’s time to build partial page class and clean all code out from Razor page. Image on right shows how page files are nested in Visual Studio. There are two files. With orange icon there’s class and we can start browsing it by structure when clicking on the icon.
Here is the code I have in FetchData partial class.
public partial class FetchData
{
[Inject]
public WeatherForecastService ForecastService { get; set; }
private WeatherForecast[] forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
}
}
Now we can remove all code and attributes from Razor page.
@page "/fetchdata"
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from a service.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
As a result we have smaller page and clean partial class behind it. We won on both fronts.
Multiple partial classes are supported! If you want to have more than one file for partial class of page then you can do it. It will be supported. Just name class files like FetchData.razor.internals.cs and FetchData.razor.data.cs and make sure you make class definitions partial in those files.
Comparing partial to code-behind class
As I said it’s also possible to write code-behind classes for Razor pages and make pages inherit from code-behind classes. Example and full discussion about code-behind is available in my blog post Code-behind with Blazor pages.
There are few differences between using partial and code-behind class.
- Partial class – all parts of partial class are compiled together to one class. It’s all the same class just split to multiple files. In case of partial page class private members of code-behing class are visible in page.
- Code-behind class – when using inheritance (@inherits directive on Blazor page) then page and it’s code-behind are two classes. Page class will inherit from code-behind class. Private members of code-behind class will not be visible to page. Minimum level is protected.
Which way to go? Like architects love to say – it depends!
Wrapping up
Although I prefer to use code-behind classed to keep all kind of dirty work and private scope secrets away from page it’s nice to have also partial page class as an option. Those not so familiar with Blazor-Razor-ASP.NET Core may find partial page classes to be an easier way to start separating code from presentation.
View Comments (3)
This is a nice development, and one that I will explore, during my upcoming 'learning BLazor by porting a an MVC project' session.
One aspect of code-behind/partial-classes that hasn't been mentioned is how each of these can (or cannot) be used in a unit testing scenario - I guess that's something else for me to experiment with.
Thanks for the great articles - keep them coming.
Very happy about this addition. This seems to be a VS 2019 thing only. Doesn't work in VSCode. I believe there are some work being done to get this working.
https://github.com/aspnet/AspNetCore/issues/15172
What about the Shared razor pages that don't have @page at the top to link them up? Or is it linked via file name so "NavMenu.razor"will look for NavMenu.razor.cs?