.NET 10.0 Preview 4 setzt Fokus auf Webentwicklung
Die vierte Vorschauversion von .NET 10.0 liefert hauptsächlich Verbesserungen für auf ASP.NET Core basierdende Web-APIs und das Webfrontend-Framework Blazor.
(Bild: Pincasso/Shutterstock.com)
- Dr. Holger Schwichtenberg
.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.
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.
Videos by heise
(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<T> 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<JsonPatchDocument<Person>>(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:
<Target Name="AddOpenApiDependencies" AfterTargets="ResolveReferences">
<ItemGroup>
<!-- Include XML documentation for ProblemDetails -->
<AdditionalFiles
Include="@(ReferencePath->'%(RootDir)%(Directory)%(Filename).xml')"
Condition="'%(ReferencePath.Filename)' == 'Microsoft.AspNetCore.Http.Abstractions'"
KeepMetadata="Identity;HintPath" />
</ItemGroup>
</Target>
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:
| Property | Default | Set value to… | Description |
| <WasmPerfTracing> | false | true | Enables support for WebAssembly performance tracing. |
| <WasmPerfInstrumentation> | none | all | Enables instrumentation necessary for the sampling profiler. |
| <EventSourceSupport> | false | true | Enables EventPipe support. |
| <MetricsSupport> | false | true | Enables System.Diagnostics.Metrics support. |
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.
(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<string>("text");
var textLength = await jsObj.InvokeAsync<int>("getTextLength");