DEV Community

Cover image for ASP.NET Core in .NET 8 is On The Way! 5 New Features Reviewed
ByteHide
ByteHide

Posted on • Updated on • Originally published at bytehide.com

ASP.NET Core in .NET 8 is On The Way! 5 New Features Reviewed

In this article, we delve into the exciting new features and updates introduced in ASP.NET Core .NET 8 Preview 3.

We will explore the addition of ASP.NET Core support for native AOT, server-side rendering with Blazor, rendering Razor components outside of ASP.NET Core, sections support in Blazor, monitoring Blazor Server circuit activity, SIMD enabled by default for Blazor WebAssembly apps, request timeouts, and short circuit routes.

Join us as we take a closer look at these enhancements and how they can improve your web development experience!

Native AOT in ASP.NET Core

Hold onto your hats! .NET 8 Preview 3 brings Native AOT (Ahead of Time) support for ASP.NET Core, perfect for cloud-native API apps. Now, publishing an ASP.NET Core app with native AOT creates a self-contained app AOT compiled to native code. No more need for the .NET runtime on the machine!

Why native AOT rocks in ASP.NET Core

ASP.NET Core apps with native AOT have a smaller footprint, lightning-fast startup, and use less memory. How cool is that? Plus, the benefits shine in workloads with many instances like cloud infrastructure and massive services.

Native AOT offers:

  • Smaller disk footprint: One executable contains the program and used code from external dependencies, leading to smaller container images and quicker deployment.
  • Faster startup time: No more JIT compilation means the app is ready in a jiffy, making deployments with container orchestrators a breeze.
  • Lower memory use: With less memory needed, you’ll see better deployment density and scalability.

In Microsoft’s tests, a simple ASP.NET Core API app with native AOT saw 80% faster startup time and 87% smaller app size. That’s a game-changer!

Minimal APIs Meet Native AOT

Get ready for a fantastic combo! Minimal APIs are now compatible with native AOT, thanks to the Request Delegate Generator (RDG). As a source generator, RDG turns those MapGet(), MapPost(), and other calls into RequestDelegates with routes during compile-time. No more runtime code generation!

RDG comes to life when you enable native AOT publishing. Want to test your project’s readiness for native AOT or reduce startup time? Manually enable RDG with <EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator> in your project file.

Minimal APIs love JSON payloads, so the System.Text.Json source generator steps in to handle them. Just register a JsonSerializerContext with ASP.NET Core’s dependency injection.

Check Microsoft example:

// Register the JSON serializer context with DI
builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.AddContext<AppJsonSerializerContext>();
});

...
// Add types used in your Minimal APIs to source generated JSON serializer content
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
}
Enter fullscreen mode Exit fullscreen mode

Now you’ve got a powerful mix of Minimal APIs and native AOT!

Get Started with Native AOT-ready Templates

a

Source: Microsoft

In this preview, Microsoft unveils two native AOT-enabled project templates for ASP.NET Core.

The “ASP.NET Core gRPC Service” template now has an “Enable native AOT publish” option. Tick that box, and <PublishAot>true</PublishAot> pops up in your .csproj file.

Introducing the fresh “ASP.NET Core API” template, designed for cloud-native, API-first projects. It’s different from the “Web API” template because it:

  • Only uses Minimal APIs (no MVC yet)
  • Employs WebApplication.CreateSlimBuilder for essential features
  • Listens to HTTP only (cloud-native deployments handle HTTPS)
  • Skips IIS or IIS Express launch profiles
  • Enables JSON serializer source generator for native AOT
  • Swaps weather forecast sample for a “Todos API”
  • Temporarily uses Workstation GC to minimize memory use

Create a new API project with native AOT using the dotnet CLI:

$ dotnet new api -aot
Enter fullscreen mode Exit fullscreen mode

The new “ASP.NET Core API” template generates this Program.cs content as you can see in the Microsoft example:

using System.Text.Json.Serialization;
using MyApiApplication;

var builder = WebApplication.CreateSlimBuilder(args);
builder.Logging.AddConsole();
builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.AddContext<AppJsonSerializerContext>();
});
var app = builder.Build();
var sampleTodos = TodoGenerator.GenerateTodos().ToArray();
var todosApi = app.MapGroup("/todos");
todosApi.MapGet("/", () => sampleTodos);
todosApi.MapGet("/{id}", (int id) =>
    sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
        ? Results.Ok(todo)
        : Results.NotFound());
app.Run();
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
}
Enter fullscreen mode Exit fullscreen mode

Ready, set, go with native AOT templates!

Manage Request Timeouts

In this preview release, Microsoft presents a new middleware for handling request timeouts. Now, you can easily set timeouts for specific endpoints, controllers, or on-the-fly per request.

First, add the request timeout services:

builder.Services.AddRequestTimeouts();
Enter fullscreen mode Exit fullscreen mode

Next, apply request timeouts using middleware with UseRequestTimeouts():

app.UseRequestTimeouts();
Enter fullscreen mode Exit fullscreen mode

For specific endpoints, use WithRequestTimeout(timeout) or add [RequestTimeout(timeout)] to the controller or action.

Keep in mind, timeouts are cooperative. When they expire, HttpContext.RequestAborted triggers, but requests won’t be forcibly stopped. Your app should keep an eye on the token and decide when to wrap up request processing.

Quick Route Short Circuit

In this update, Microsoft introduces a new option for quicker route handling. Usually, when a route matches an endpoint, the middleware pipeline runs before invoking the endpoint logic. However, you might not need this for certain requests, like robots.txt or favicon.ico.

Use the ShortCircuit() option to immediately invoke the endpoint logic and end the request:

app.MapGet("/", () => "Hello World").ShortCircuit();
Enter fullscreen mode Exit fullscreen mode

For quickly sending a 404 or another status code without further processing, try MapShortCircuit:

app.MapShortCircuit(404, "robots.txt", "favicon.ico");
Enter fullscreen mode Exit fullscreen mode

This efficient approach bypasses unnecessary features like authentication and CORS.

Blazor’s Handy Sections

Microsoft introduces SectionOutlet and SectionContent components in Blazor, making it easy to create content placeholders in layouts. These sections can later be filled by specific pages using unique names or object IDs.

For instance, add a SectionOutlet to the top row of MainLayout in a Blazor template. Don’t forget to include the Microsoft.AspNetCore.Components.Sections directive in the root _Imports.razor file:

@using Microsoft.AspNetCore.Components.Sections
...
<div class="top-row px-4">
    <SectionOutlet SectionName="TopRowSection" />
    <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
Enter fullscreen mode Exit fullscreen mode

Now, pages can display content in the TopRowSection using SectionContent. In Counter.razor, you could add a button to increment the counter:

<SectionContent SectionName="TopRowSection">
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</SectionContent>
Enter fullscreen mode Exit fullscreen mode

Sections make organizing content a breeze!

Top comments (4)

Collapse
 
mellen profile image
Matt Ellen

Native Attack On Titan? I'm not sure what that means. Does the framework turn into a much larger framework and eat other frameworks?

Collapse
 
marissab profile image
Marissa B

Lol that one threw me too. I hadn't heard of it before but the linked Microsoft docs page said what it was. "ASP.NET Core 8.0 introduces support for .NET native ahead-of-time (AOT)."

Collapse
 
mellen profile image
Matt Ellen

Ah! Thank you.

Collapse
 
dsalum profile image
Daniel

Hola, estoy probando tema AddRequestTimeouts agregando un timeout en un controller, pero no me funciona; comento la implementación por si me pueden ayudar:
En Program.cs agrego:
using Microsoft.AspNetCore.Http.Timeouts;
builder.Services.AddRequestTimeouts();
app.UseRequestTimeouts();

//UseRequestTimeouts está incluído posterior
a app.UseRouting(); tal como indica la documentación.
En Controlador agrego un timeout de 10 segundos:

[HttpPost]
[RequestTimeout(10000)]
public IActionResult Post([FromBody] PedidoBasico pedidoBasico)
..........
..........
..........

El server no lo ejecuto en modo debug tal como lo indica la documentación.
A mi entender, al hacer un Post con una demora prolongada, debería cortar a los 10 segundos, pero NO lo hace.

No me doy cuenta si me falta agregar algo en el código.