What new features are in ASP.NET Core 8.0? Let's have an explore!
The latest version of Microsoft’s enterprise web development platform is here. Our resident ASP.NET expert puts on his C# boots for a bit of an explore around the new features of ASP.NET Core 8.0!
29-02-2024
The new release of .NET has been out a few months now, and as ever there are big improvements across all areas. While the changes to C# 12 are somewhat minimal compared to earlier releases, when it comes to ASP.NET, there are lots of new features.
On the Server
As we shall see, the changes to Blazor mean that distinctions between client- and server-side code are becoming increasingly hard to recognize. But not everybody uses Blazor, so here are some features that Web API and MVC developers can take advantage of too.
Keyed Dependency Injection
DI has been around in ASP.NET Core since the beginning, but somewhat limited in its configuration:
Flexible enough, but everybody still gets the same implementation. Consider our CachedRepository. It may do caching, but ultimately, it’s going to require access to the actual DbRepository. If it requests it in its constructor via injection, we get a cyclic dependency:
public CachedRepository(IRepository realRepository)
It asks for an IRepository, and so is given a CachedRepository, which is itself.
Keyed DI makes things more precise. We can optionally configure the service with a key:
Anyone who just asks for IRepository will still get CachedRepository, but we can also make the request with the key:
public CachedRepository
(
[FromKeyedServices("raw-access")] IRepository realRepository
)
While the original mechanism is sufficient in most cases, we now have enormous flexibility when needed.
Authentication Endpoints
There have been several improvements to authentication and authorization, but one of the neatest is in the area of Web API. For MVC or Razor Pages apps, when you add authentication, you get for free a load of predefined pages for registration, login, etc. With Web API, you don’t want pages, but you do want endpoints for those functions – and previously, you had to write them for yourself.
Now it can all be done in a few lines of configuration:
builder.Services.AddDbContext<AuthenticationContext>();
builder.Services.AddIdentityApiEndpoints<IdentityUser>()
.AddEntityFrameworkStores<AuthenticationContext>();
var app = builder.Build();
app.MapGroup("/identity").MapIdentityApi<IdentityUser>();
Straightaway we have endpoints such as ‘/identity/register’, ‘/identity/login’, ‘/identity/refresh’ etc - in fact ten new endpoints, covering all the actions you might want to take regarding authentication.
Of course, it’s all highly configurable, or you can bypass it and do the work for yourself, but it’s a really fast way to get started.
Native AOT
Remember what you learned about the .NET compilation model? Well now you can forget it – or at least look to an alternative. Traditionally, C# compiles down to Intermediate Language (IL), which is deployed to your target platform, where the .NET runtime uses a Just in Time (JIT) compiler to generate native machine code.
The benefit is portability - the same Intermediate Language will run anywhere. But there can be a downside in terms of performance.
Now we have the option to replace JIT with AOT – Ahead of Time compilation. Our C# compiles directly to native code, and that’s what we ship.
Now we have to provide different versions of the distributable for different platforms – though for a cloud-hosted website, there’s probably only one (and it’s probably Linux). The benefits can (emphasis on can) be smaller app size, quicker startup, lower memory use and better performance. Moreover, the deployment platform does not need to have .NET installed at all, adding to the much smaller footprint.
There are downsides. Entire areas of .NET simply cannot be used with AOT, most importantly Reflection, since Reflection inspects the IL. And in ASP.NET, Reflection is really important – that’s how JSON serialization works. Fortunately, this problem has been solved using JSON source generation, where the work that would have been done by Reflection at runtime can now be done at compile time, inspecting the source code rather than the IL. However, if your using any third-party packages, they may use Reflection and so may not work with AOT. But as AOT takes off, more and more packages are being converted to work with it.
As with any performance issue, the proof is in the pudding, and the actual performance advantage will vary depending on circumstances. Do some benchmarking and see what benefits you’re getting.
Blazor
The intent of Blazor has always been to allow us to use the same set of tools to program both the client and the server. There’s no attempt to exclude other front-end technologies such as Angular or React, but each new release makes Blazor a better option.
Rendering Modes
There are three ways that web content can be generated using Blazor.
Static Server – For each request, the entire page is generated on the server. This is the same approach as has traditionally been taken with MVC and Razor pages.
Interactive Server – Content is still generated on the server, but only the changes are sent to be rendered on the client, using SignalR, not the whole page.
Interactive WebAssembly – New content is generated within the client by running .NET code in WebAssembly (WASM). No calls to the server a required, except to fetch data.
Traditionally, a Blazor project was created as either Blazor Server or Blazor WASM. Static server was optionally used for the initial rendering of the page in either mode. The benefit is that the initial page load can be faster, and more information is available for Web crawlers.
A New Template
Before .NET 8, developers had to make an upfront decision as to whether they were going to use Blazor Server or Blazor WASM – with different project templates for each.
Now, only one project template is required, and developers can pick and choose whether to use server- or client-side rendering. That choice could be made across the whole project, or for individual components, or even specific component instances.
Here’s the code that would instruct the Home page to use server-side rendering:
The mode could be InteractiveServer, InteractiveWebAssembly or a new one, InteractiveAuto.
Auto Rendering
Sometimes the choice between client- and server-side rendering will be forced by the type of interaction you have, but sometimes it will just be a matter of performance, and here there is a trade-off. Blazor WASM is generally faster once it gets going, but has an upfront overhead of the download of the component code to the client. Blazor Server has a smaller download.
The InteractiveAuto mode lets the system choose which mode is best. Typically, when a user first accesses a component, the mode chosen will be InteractiveServer. But meanwhile, the WASM code will be downloaded in the background, so next time they visit the component, they get faster client-side rendering. The best of both worlds.
And Much More Besides!
There are many other improvements than there is room to mention here, including new Blazor components and client-side multithreading.
To help raise awareness of challenges and vulnerabilities and ways to reduce risk, we've got a bumper crop of cyber security blog articles. We've also got a robust range of hands-on training courses covering security for non-technical staff and IT professionals
We use cookies on our website to provide you with the best user experience. If you're happy with this please continue to use the site as normal. For more information please see our Privacy Policy.