What's New In .NET Core 3.0 For Razor Pages

Later this year, .NET Core 3.0 will be released. The main features include WPF and Windows Forms support (albeit only on the Windows operating system) and server-side Blazor. Razor Pages applications will also see some changes. I cover some of these as part of a guide to upgrading an application from 2.2 to 3.0. Then I have a quick look at some of the other new features. Note that the information in this article is based on Preview 6, and is subject to change.

For a lot of developers, the changes that affect Razor Pages applications are not much more than implementation details, which explains why upgrading from 2.2 to 3.0 is actually a pretty simple procedure described in the following steps:

1. Change the target framework. This is done in the csproj file. Modify it so that it says netcoreapp3.0:

<PropertyGroup>
  <TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

2. In ConfigureServices, replace services.AddMvc(); with services.AddRazorPages();. This adds Razor Pages-specific services, options and conventions, as well as some more general services that are rooted in MVC such as Views, TempData, AntiForgery, Tag Helpers etc. It also adds basic support for controllers, so if you want to add some API controllers, you don't need to add any other services.

3. In the Configure method, replace app.UseMvc(); with

app.UseRouting();

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
});

This adds EndPointRoutingMiddleware followed by EndPointMiddleware. The MapRazorPages call ensures that endpoint routing is set up for Razor Pages. If you wanted to add routing for controllers, you would include endpoints.MapControllers(); to the lambda:

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapControllers();
});

EndPoint Routing was introduced as part of 2.2, but it wasn't exposed to Razor Pages at that time. In 3.0, it is the default routing system. Instead of routing being managed as part of MVC, it has been split out into a separate service, which means that you can be flexible about where it is added in the middleware pipeline. What this means in practice is that you can access routing information anywhere with the pipeline after the call to app.UseEndpoints. This is useful if you want to add middleware that performs tasks based on the route. Previously, you only had access to information about the URL that the request came in on. Now you have access to information about the route that matches the URL.

And that's it with regard to upgrading. So what else is new?

New JSON Reader and Writer

ASP.NET Core applications use a new component for managing JSON - System.Text.Json. This is part of CoreFX and replaces Json.NET, a community library. If you are upgrading an application that explicitly relies on JSON.Net, you will need to opt in to using it, which you can do by installing Microsoft.AspNetCore.Mvc.NewtonsoftJson from Nuget. This adds JSON.Net to the project and makes an extension method available to IServiceCollection - AddNewtonsoftJson, which you can chain with AddRazorPages in ConfigureServices:

services.AddRazorPages().AddNewtonsoftJson();

System.Text.Json is optimised for speed. It makes use of some new C# 8.0 types which .NET Core 3.0 also supports.

Razor Components

Razor Components are the building blocks for Blazor applications. But you can also use them in a Razor Pages application, where they act in a similar way to both partials and View Components, representing a portion of UI. Here's a simple example by way of introduction.

To enable Razor Components, you need to call

services.AddServerSideBlazor();

Razor Component is available as an option in the Add New Item dialog:

Depending on your version of VS 2019 Preview, this may generate a .cshtml file or a .razor file. If it generates a .cshtml file, change the extension to razor. I've called my file DemoComponent.razor and added an h2 element to the default content that renders the current time:

<h3>DemoComponent</h3>
<h2>@DateTime.Now</h2>


@code {

}

I saved this in a folder name RazorComponents. The generated class will automatically be assigned a namespace that matches the folder path. A new method has been added to the Html helper - RenderComponentAsync, which is used to include the component in a Razor Page

@(await Html.RenderComponentAsync<RazorComponents.DemoComponent>())

Razor Components are a lot more powerful than this. They can accept parameters for example and you can build complex ones through composing multiple components.

Summary

As I alluded to at the beginning, most of the changes that affect Razor Pages (and MVC) in .NET Core 3.0 are unlikely to surface in the majority of applications. You can be slightly more selective about the components that you include in your application, rather than always adding MVC, and there are some potentially useful features around the new routing story. But route declaration and management in Razor Pages is pretty much the same as before. Probably the most notable feature is the ability to use Razor Components, which I plan to look at in more detail in future posts.