.NET 9.0 Preview 7: Neues für AOT-Kompilierung und Cross-Plattform mit .NET MAUI

Die neueste Vorschauversion auf .NET 9.0 weitet den in .NET integrierten Ahead-of-Time-Compiler auf bidirektionale Dienste mit ASP.NET Core SignalR aus.

In Pocket speichern vorlesen Druckansicht 1 Kommentar lesen
.NET-Bild

(Bild: Pincasso/Shutterstock.com)

Lesezeit: 13 Min.
Von
  • Dr. Holger Schwichtenberg
Inhaltsverzeichnis

Microsoft hat die siebte Vorschauversion für .NET 9.0 veröffentlicht – mit Neuerungen für Native AOT. Diesen Ahead-of-Time-Compiler für .NET gibt es in .NET seit Version 7.0. Dort funktionierte er zunächst nur für Konsolenanwendungen. In .NET 8.0 kamen ASP.NET-Core-basierte Web-APIs und gRPC-Dienste sowie Worker Services hinzu. Seit der in dieser Woche erschienenen Preview 7 der kommenden .NET-Version 9.0 sind auch SignalR-Dienste mit Native AOT sowie das Trimming (Tree Shaking) beim Einsatz des Just-in-Time-Compilers möglich.

Allerdings gibt es bei SignalR (wie bei anderen Anwendungsarten auch) funktionale Einschränkungen in Verbindung mit Trimming und der AOT-Kompilierung. Streng typisierte Hubs sind ebenso wenig erlaubt wie die Rückgabetypen IAsyncEnumerable<T> und ChannelReader<T>. Für asynchrone SignalR-Operationen sind nur die Rückgabetypen Task, Task<T>, ValueTask und ValueTask<T> gestattet.

Bei der Datenübertragung ist ausschließlich JSON-Serialisierung mit Microsofts JSON-Serialisierer System.Text.Json und zugehörigem Source Generator möglich; kompaktere SignalR-Formate wie Message Pack sind zunächst ausgeschlossen.

Im Readme-Dokument zu den Neuerungen in ASP.NET Core 9.0 Preview 7 erwähnt Microsoft auch, dass die seit .NET 9.0 Preview 4 verfügbare OpenAPI-Metadatengenerierung mit dem NuGet-Paket "Microsoft.AspNetCore.OpenApi" nun mit Trimming und Native AOT funktioniert. Tests hatten aber zuvor schon gezeigt, dass dies bereits mit Preview 5 funktionierte. Verändert hat Microsoft in Preview 7 die bereits zuvor vorhandene Möglichkeit, OpenAPI-Transformer einzubinden: Anstelle von UseTransformer() gibt es nun getrennte Methoden für Dokumente, Schema und Operationen: AddDocumentTransformer(), AddSchemaTransformer() und AddOperationTransformer().

Die in ASP.NET Core eingebaute Implementierung für Open ID Connect, die man mit AddOpenIdConnect() aktiviert, verwendet seit .NET 9.0 Preview 7 im Standard Pushed Authorization Requests (PAR) gemäß RFC 9126. Entwicklerinnen und Entwickler können PAR aber auf Wunsch deaktivieren:

builder.Services
    .AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie()
    .AddOpenIdConnect(oidcOptions =>
    {
        // Other provider-specific configuration goes here.

        // The default value is PushedAuthorizationBehavior.UseIfAvailable.
        oidcOptions.PushedAuthorizationBehavior = PushedAuthorizationBehavior.Disable;
    });

ASP.NET Core 9.0 Preview 7 erlaubt auch erstmals das Löschen von Schlüsseln bei der seit .NET Core 1.0 integrierten Data Protection API. Dazu gibt es die neue Methode DeleteKeys() in der Schnittstelle IDeletableKeyManager. Microsoft erwähnt, dass das Löschen von Schlüsseln für sehr lange laufende Dienste sinnvoll sein könnte. Die damit verschlüsselten Daten können dann freilich nicht mehr genutzt werden. Daher positioniert sich Microsoft klar: "Our guidance remains that data protection keys shouldn't be deleted."

Bei der ExceptionHandlerMiddleware können Entwicklerinnen und Entwickler nun den HTTP-Statuscode anpassen, der bei nicht abgefangenen Laufzeitfehlern im HTTP-Header und den Problemdetails nach RFC 9457 zum Client geht:

builder.Services.AddProblemDetails();
…
app.UseExceptionHandler(new ExceptionHandlerOptions
{
    StatusCodeSelector = ex => ex is ApplicationException
        ? StatusCodes.Status503ServiceUnavailable
        : StatusCodes.Status500InternalServerError,
});

In ASP.NET Core Minimal Web-APIs ist nun der Aufruf von ProducesProblem() und ProducesValidationProblem() auch nach MapGroup(), also für ganze Gruppen von Routen erlaubt. Zudem können Entwicklerinnen und Entwickler bei ProducesProblem() und ProducesValidationProblem() die Daten nun nicht nur mit dem Typ IDictionary<string, object?>, sondern auch in Form einer Menge des Typs IEnumerable<KeyValuePair<string, object?>> übergeben. Aus dem folgenden Listing entsteht die im nachstehenden Bild gezeigte JSON-Antwort.

[HttpGet("/Fehler/Machen")]
public Results<Ok<IEnumerable<Person>>, ProblemHttpResult> FehlerMachen2()
{
 var timestamp = DateTime.Now;
 var logId = Guid.CreateVersion7(timestamp: timestamp);
 var problemData = new List<KeyValuePair<string, object>> { new("LogId", logId), new("Timestamp", timestamp) };
 return TypedResults.Problem("Diese WebAPI-Operation hat einen schwachen Moment.", extensions: problemData);
}

Listing: Controller-basierte Web-API, die einen Fehler mit eigenen Daten in den Problemdetails liefert

JSON-Antwort des obigen Listings

(Bild: Dr. Holger Schwichtenberg)

ASP.NET Core bietet Metriken für die Open Telemetry API. Bisher waren diese für alle Endpunkte aktiv. In ASP.NET Core 9.0 Preview 7 können Entwicklerinnen und Entwickler nun erstmals einzelne Endpunkte bei den Metriken ausnehmen, mit Aufruf der neuen Methode DisableHttpMetrics() beziehungsweise Verwendung der neuen Annotation [DisableHttpMetrics] auf Web-API-Controller-Klassen und einzelnen Aktionen. Dies ist etwa sinnvoll für Endpunkte, die nur zu Diagnosezwecken ständig aufgerufen werden, beispielsweise

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();

var app = builder.Build();
app.MapHealthChecks("/apicheck").DisableHttpMetrics();
app.Run();

Die Annotation [DisableHttpMetrics] können Entwicklerinnen und Entwickler nicht nur für Web-APIs, sondern auch gRPC-Dienste und SignalR-Hubs nutzen.

Bei dem in ASP.NET Core integrierten Serverprozess Kestrel sind seit der .NET-Version 8.0 auch Named-Pipes-Dienste möglich. Die nun in .NET 9.0 bereitgestellte Methode CreateNamedPipeServerStream() erlaubt das Anpassen einzelner Named-Pipe-Endpunkte, etwa das Festlegen von Puffergrößen. Zudem bietet Kestrel eine verbesserte Metrik: Bei der Metrik kestrel.connection.duration erhalten Nutzer nun auch Informationen über die Ursache eines Verbindungsabbruchs, zum Beispiel Timeout, zu viele Daten oder fehlgeschlagener TLS-Handshake.

Online-Konferenz zu .NET 9.0 am 19. November

(Bild: Dmytro Vikarchuk/Shutterstock))

In der Online-Konferenz betterCode() .NET 9.0 am 19. November 2024 von iX und dpunkt.verlag präsentieren .NET-Experten von www.IT-Visions.de den fertigen Stand von .NET 9.0 anhand von Praxisbeispielen. Dazu zählen die Neuerungen in .NET 9.0 SDK, C# 13.0, ASP.NET Core 9.0, Blazor 9.0, Windows Forms 9.0, WPF 9.0, WinUI, .NET MAUI 9.0 und die Integration von Künstlicher Intelligenz in .NET-Anwendungen. Das Programm bietet sechs Vorträge, eine Diskussion und sechs Workshops.

Tickets sind zum Frühbucherpreis erhältlich.

Neben den zahlreichen Verbesserungen in ASP.NET Core finden sich die meisten Verbesserungen in Preview 7 für das Cross-Platform-UI-Framework .NET MAUI (Multi-Platform App UI), das in den ersten Preview-Versionen nicht viele Neuerungen erhalten hatte.

Mit dem neuen Steuerelement <HybridWebView>, einer speziellen Form des Steuerelements <WebView>, können Entwicklerinnen und Entwickler beliebige Single-Page-Web-Apps mit HTML, CSS und JavaScript in .NET-MAUI-Oberflächen einbinden und mit diesen Inhalten interagieren. Bisher war dies per <BlazorWebView> schon mit Blazor/C#-Anwendungen möglich. Nun können Entwicklerinnen und Entwickler auch Anwendungen mit Angular, React, Vue.js und Co auf gleiche Weise wie Blazor in den MAUI-Prozess einbinden.

Die Webanwendung muss für die Interaktion ein von MAUI geliefertes Skript <script src="scripts/HybridWebView.js"></script> laden. Ein Beispiel zeigen die Release Notes. Das Basissteuerelement <WebView> für Webinhalte bietet zudem nun ein Ereignis ProcessTerminated(), für den Fall, dass der Browser abstürzt.

Mit dem weiteren neuen Steuerelement <TitleBar> und der neuen Eigenschaft Window.TitleBar lässt sich nun für Windows-Anwendungen leichter der Inhalt der Titelleiste setzen. In einer kommenden MAUI-Version soll dies auch mit Mac Catalyst funktionieren. Sowohl in Windows als auch Mac Catalyst gibt es seit .NET 9.0 Preview 7 die Möglichkeit, in einer MAUI-Anwendung ein Fenster in den Vordergrund zu bringen:

Application.Current?.ActivateWindow(window);

Zudem gibt es Breaking Changes für .NET MAUI in Preview 7 in Bezug auf die Startseite und die beim Steuerelement <BlazorWebView> verwendete Host-Adresse (nun localhost statt 0.0.0.0). Man kann aber <BlazorWebView> weiterhin dazu bewegen, 0.0.0.0 zu nutzen, indem man in Program.cs Folgendes setzt:

AppContext.SetSwitch("BlazorWebView.AppHostAddressAlways0000", true);