.NET 10.0 Preview 4 steht seit gestern zum Download auf der .NET-Downloadseite bereit. Die Neuerungen betreffen insbesondere die Webentwicklung mit neuen, auf ASP.NET Core basierenden Web-APIs und Verbesserungen beim Blazor-Framework.
Dr. Holger Schwichtenberg ist Chief Technology Expert bei der MAXIMAGO-Softwareentwicklung. Mit dem Expertenteam bei www.IT-Visions.de bietet er zudem Beratung und Schulungen im Umfeld von Microsoft-, Java- und Webtechniken an. Er hält Vorträge auf Fachkonferenzen und ist Autor zahlreicher Fachbücher.
Parallel dazu ist Visual Studio 2022 Version 17.14 in einer stabilen Version erschienen. Anders als bisher gibt es für Visual Studio keine neue Preview-Version 17.5, sondern eine Version 17.14 Preview 7. Da nächste Woche vom 19. bis 22. Mai die Build-Konferenz 2025 von Microsoft in Seattle und online stattfindet, könnte Microsoft dort die Perview einer neuen Hauptversion präsentieren. Das letzte Major Release vor Visual Studio 2022 war Visual Studio 2019.
Parallel zu .NET 10.0 ist Visual Studio 2022 Version 17.14 als Preview 7 erschienen.
(Bild: Screenshot (Holger Schwichtenberg))
JSON Patch für System.Text.Json und ASP.NET Core-basierte Web-APIs
ASP.NET Core 10.0 beherrscht nun den JSON-Patch-Standard nach RFC 6902 auch in Verbindung mit Microsofts JSON-Serialisierer System.Text.Json mithilfe des Zusatzpakets Microsoft.AspNetCore.JsonPatch.SystemTextJson
Bisher war JSON Patch nur in Verbindung mit der älteren Bibliothek Newtonsoft.Json möglich. Microsoft verspricht im Vergleich dazu in den Release Notes eine verbesserte Leistung und weniger Speichernutzung in Verbindung mit einem ähnlichen Design wie bei Newtonsoft.Json, einschließlich der Aktualisierung eingebetteter Objekte und Arrays. Bisher nicht verfügbar ist JSON Patch für dynamische Objekte, weil Newtonsoft.Json dafür Reflection einsetzt, System.Text.Json soll aber auch mit dem NativeAOT-Compiler funktionieren.
Im NuGet-Paket Microsoft.AspNetCore.JsonPatch.SystemTextJson gibt es eine Klasse JsonPatchDocument mit einer Methode ApplyTo(obj), die eine JSON Patch-Operation auf das übergebene Objekt anwendet, wie in folgendem Code aus den Release Notes:
// Original object
var person = new Person
{
FirstName = „John“,
LastName = „Doe“,
Email = „johndoe@gmail.com“,
PhoneNumbers = [new() { Number = „123-456-7890“, Type = PhoneNumberType.Mobile }],
Address = new Address
{
Street = „123 Main St“,
City = „Anytown“,
State = „TX“
}
};
// Raw JSON patch document
string jsonPatch = „““
[
{ „op“: „replace“, „path“: „/FirstName“, „value“: „Jane“ },
{ „op“: „remove“, „path“: „/Email“},
{ „op“: „add“, „path“: „/Address/ZipCode“, „value“: „90210“ },
{ „op“: „add“, „path“: „/PhoneNumbers/-„, „value“: { „Number“: „987-654-3210“, „Type“: „Work“ } }
]
„““;
// Deserialize the JSON patch document
var patchDoc = JsonSerializer.Deserialize>(jsonPatch);
// Apply the JSON patch document
patchDoc!.ApplyTo(person);
// Output updated object
Console.WriteLine(JsonSerializer.Serialize(person, serializerOptions));
Der Code erzeugt folgendes Ergebnis:
Output:
{
„firstName“: „Jane“,
„lastName“: „Doe“,
„address“: {
„street“: „123 Main St“,
„city“: „Anytown“,
„state“: „TX“,
„zipCode“: „90210“
},
„phoneNumbers“: [
{
„number“: „123-456-7890“,
„type“: „Mobile“
},
{
„number“: „987-654-3210“,
„type“: „Work“
}
]
}
Abrundung für vorherige Neuerungen
Seit ASP.NET Core 10.0 Preview 3 gibt es Validierung von Parametern auch in Minimal Web-APIs. In Preview 4 funktioniert das auch, wenn die Parameter ein Record-Typ sind.
Die ebenfalls zuvor eingeführte Berücksichtigung der XML-Dokumentation bei der OpenAPI-Dokumenten kann nun auf XML-Kommentare aus anderen Assemblies ausgedehnt werden. In den Release Notes zeigt Microsoft ein Codebeispiel, das die XML-Kommentare aus der SDK-Assembly Microsoft.AspNetCore.Http einbindet:
‚%(RootDir)%(Directory)%(Filename).xml‘)“
Condition=“‚%(ReferencePath.Filename)‘ == ‚Microsoft.AspNetCore.Http.Abstractions'“
KeepMetadata=“Identity;HintPath“ />
Diagnosedaten für Blazor WebAssembly
Eine größere neue Funktion bekommt die WebAssembly-basierte Variante von Blazor, die als Single-Page-App im Webbrowser läuft: Entwicklerinnen und Entwickler können dort zur Laufzeit Diagnosedaten zu Performance, Speicherinhalt und diverse Metriken sammeln. Dazu müssen sie die .NET WebAssembly Build Tools in der aktuellen Version installieren (dotnet workload install wasm-tools) und in der Projektdatei die Einträge folgender Tabelle aus den Release Notes:
Danach kann man per JavaScript-APIs auf die Diagnosedaten zugreifen:
// Collect a performance profile using CPU sampling for a specified duration.
globalThis.getDotnetRuntime(0).collectCpuSamples({durationSeconds: 60});
// Collect metrics for a specified duration.
globalThis.getDotnetRuntime(0).collectPerfCounters({durationSeconds: 5});
// Collect a memory dump.
globalThis.getDotnetRuntime(0).collectGcDump();
Das Ergebnis ist eine .nettrace-Datei, die man in Visual Studio betrachten kann. Alternativ kann man auch die Performance-Werkzeuge des Webbrowsers verwenden.
Der Edge Browser zeigt die WebAssembly-Leistungsdaten.
(Bild: Microsoft)
Interoperabilität zwischen C# und JavaScript
In Blazor erweitert Microsoft die Schnittstellen für die Interoperabilität zwischen C# und JavaScript (IJSRuntime, IJSObjectReference, IJSInProcessRuntime und IJSInProcessObjectReference) um neue Mitglieder. InvokeNew() und InvokeNewAsync() erzeugen eine Instanz von einem JavaScript-Objekt. Außerdem gibt es Methoden, um Objekteigenschaften zu lesen (GetValue() und GetValueAsync()) und zu setzen (SetValue() und SetValueAsync()).
Bisher konnte man von C# aus nur Funktionen in JavaScript mit Invoke(), InvokeVoid(), InvokeAsync() und InvokeVoidAsync() aufrufen. Die neuen Interopabilitätsmethoden vermeiden in einigen Fällen, dass man eine JavaScript-Funktion schreiben muss. Stattdessen kann man nun direkt Objekte erzeugen und Werte lesen sowie schreiben. Für die JavaScript-Klasse
window.TestClass = class {
constructor(text) {
this.text = text;
}
getTextLength() {
return this.text.length;
}
}
zeigt ein Codebeispiel in den Release Notes, den Einsatz der neuen Methoden:
var jsObj = await JSRuntime.InvokeNewAsync(„jsInterop.TestClass“, „Blazor!“);
var text = await jsObj.GetValueAsync(„text“);
var textLength = await jsObj.InvokeAsync(„getTextLength“);