March 14th, 2023
heart10 reactions

ASP.NET Core updates in .NET 8 Preview 2

Daniel Roth
Principal Product Manager

.NET 8 Preview 2 is now available and includes many great new improvements to ASP.NET Core.

Here’s a summary of what’s new in this preview release:

  • Blazor QuickGrid component
  • Improved Blazor WebAssembly performance with the jiterpreter
  • New analyzer to detect multiple FromBody attributes
  • New APIs in ProblemDetails to support more resilient integrations
  • New IResettable interface in ObjectPool
  • Performance improvements to named pipes transport

For more details on the ASP.NET Core work planned for .NET 8 see the full ASP.NET Core roadmap for .NET 8 on GitHub.

Get started

To get started with ASP.NET Core in .NET 8 Preview 2, install the .NET 8 SDK.

If you’re on Windows using Visual Studio, we recommend installing the latest Visual Studio 2022 preview. Visual Studio for Mac support for .NET 8 previews isn’t available at this time.

Upgrade an existing project

To upgrade an existing ASP.NET Core app from .NET 8 Preview 1 to .NET 8 Preview 2:

  • Update the target framework of your app to net8.0.
  • Update all Microsoft.AspNetCore.* package references to 8.0.0-preview.2.*.
  • Update all Microsoft.Extensions.* package references to 8.0.0-preview.2.*.

See also the full list of breaking changes in ASP.NET Core for .NET 8.

Blazor QuickGrid component

The Blazor QuickGrid component is now part of .NET 8! QuickGrid is a high performance grid component for displaying data in tabular form. QuickGrid is built to be a simple and convenient way to display your data, while still providing powerful features like sorting, filtering, paging, and virtualization.

To get started with QuickGrid:

  1. Add reference to the Microsoft.AspNetCore.Components.QuickGrid package.

    dotnet add package Microsoft.AspNetCore.Components.QuickGrid --prerelease
  2. Add the following Razor code to render a very simple grid.

    <QuickGrid Items="@people">
        <PropertyColumn Property="@(p => p.PersonId)" Title="ID" Sortable="true" />
        <PropertyColumn Property="@(p => p.Name)" Title="Name" Sortable="true" />
        <PropertyColumn Property="@(p => p.BirthDate)" Title="Birth date" Format="yyyy-MM-dd" Sortable="true" />
    </QuickGrid>
    
    @code {
        record Person(int PersonId, string Name, DateOnly BirthDate);
    
        IQueryable<Person> people = new[]
        {
            new Person(10895, "Jean Martin", new DateOnly(1985, 3, 16)),
            new Person(10944, "António Langa", new DateOnly(1991, 12, 1)),
            new Person(11203, "Julie Smith", new DateOnly(1958, 10, 10)),
            new Person(11205, "Nur Sari", new DateOnly(1922, 4, 27)),
            new Person(11898, "Jose Hernandez", new DateOnly(2011, 5, 3)),
            new Person(12130, "Kenji Sato", new DateOnly(2004, 1, 9)),
        }.AsQueryable();
    }

    QuickGrid

You can see various examples of QuickGrid in action on the QuickGrid demo site.

QuickGrid was originally introduced as an experimental package based on .NET 7. As part of bringing QuickGrid into .NET 8 we’ve made some changes and improvements to the API. To update an existing Blazor app that uses QuickGrid to the .NET 8 version, you may need to make the following adjustments:

  • Rename the Value attribute on the Paginator component to State
  • Rename the IsDefaultSort attribute on columns to InitialSortDirection and add IsDefaultSortColumn=true to indicate the column should still be sorted by default.
  • Remove the ResizableColumns attribute on QuickGrid. Built-in support for resizable columns was removed.

Improved Blazor WebAssembly performance with the jiterpreter

The jiterpreter is a new runtime feature in .NET 8 that enables partial JIT support in the .NET IL interpreter to achieve improved runtime performance.

Blazor WebAssembly apps are able to run .NET code in browser thanks to a small .NET runtime implemented in WebAssembly that gets downloaded with the app. This runtime is a .NET IL interpreter that is fully functional, reasonably small in size, and allows for fast developer iteration, but lacks the runtime performance benefits of native code execution through just-in-time (JIT) compilation. JITing to WebAssembly requires creating new WebAssembly modules on the fly and instantiating them, which poses unique challenges for the runtime. Blazor WebAssembly apps can instead choose to compile ahead-of-time (AOT) to WebAssembly to improve runtime performance but at the expense of a much larger download size. Since some common .NET coding patterns are incompatible with AOT, the .NET IL interpreter is still needed as a fallback mechanism to maintain full functionality.

The jiterpreter optimizes execution of interpreter bytecodes by replacing them with tiny blobs of WebAssembly code. By leveraging the interpreter as a baseline, we’re able to optimize the most important parts of the app without having to handle more complex or obscure cases and without overly complicating the runtime. While the jiterpreter isn’t a full JIT implementation, it significantly improves runtime performance without the size and build time overhead of AOT. The jiterpreter helps when using AOT too by optimizing cases where the runtime has to fallback to the interpreter.

In .NET 8 Preview 2 The jiterpreter is automatically enabled for your Blazor WebAssembly apps. You don’t have to do anything extra to turn it on.

The jiterpreter can significantly speed up the performance of low level operations. For example, the following micro benchmark test for Span<byte>.Reverse() and String.Normalize() ran 46.7% and 86.9% faster respectively:

Jiterpreter performance for low level operations

These improvements add up and translate into better performance for higher layer features. In our JSON serialization tests, the jiterpreter is 40.8% faster:

Jiterpreter performance for JSON serialization

We’re still working to improve the jiterpreter with