© RDK03/Shutterstock.com, © S&S Media
Web Services aufrufen mit Blazor

Mit Blazor zu Diensten


Blazor kann sowohl REST-Dienste/Web-APIs als auch Google-RPC-basierte Web Services nutzen. Dieser Artikel zeigt anhand eines Beispiels, wie Web-API- und gRPC-basierte Web Services in Blazor genutzt werden können und worauf dabei zu achten ist.

In Blazor-Server-basierten Webanwendungen kann man direkt auf Datenbankmanagementsysteme zugreifen, denn hier stehen alle .NET-APIs und Netzwerkprotokolle zur Verfügung. Blazor WebAssembly hingegen läuft in der Sandbox des Browsers. Man kann zwar Bibliotheken wie System.Data.dll und Microsoft.EntityFrameworkCore.SqlServer.dll in den Browser laden, aber damit keine Kommunikation zu einem Datenbankmanagementsystem aufbauen. SOAP und damit auch die Windows Communication Foundation (WCF) sind aus der Sicht von Microsoft nicht mehr zeitgemäß. Microsoft setzt stattdessen in .NET Core, .NET 5 und Blazor auf REST-Dienste/Web-APIs und Google Remote Procedure Call (gRPC).

Szenario

Im Folgenden wird die Verwendung von Web-API- und gRPC-basierten Web Services in Blazor anhand eines Beispiels mit zwei typischen Operationen vorgestellt:

  • GetFlight(string ort, int maxCount = 0): laden einer Menge von Flügen von einem Ort mit optionaler Mengenbegrenzung

  • SaveFlight(BO.Flug flug, bool force = false): speichern eines Flugobjekts, optional mit der Möglichkeit, zwischenzeitliche Änderungen anderer Benutzer gnadenlos zu überschreiben

Die Implementierung beider Operationen mit Hilfe von Entity Framework Core zeigt Listing 1. Auf den Abdruck der zugehörigen Entitätsklasse Flug sowie der Kontextklasse wird hier verzichtet. Der komplette Programmcode ist online [1] zu finden.

Listing 1: Businesslogik für die Entitäten des Typs Flug

using DAL; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; namespace WWWings.BL {  /// <summary>  /// Manager für Entitäten des Typs Flug  /// </summary> public class BLManager { public List<BO.Flug> GetFlight(string ort, int maxCount = 0) { EFContext ctx = new EFContext(); var query = (from f in ctx.Flug select f); if (!string.IsNullOrEmpty(ort)) query = query.Where(f=> f.Abflugort == ort); if (maxCount > 0) query = query.Take(maxCount); return query.ToList(); } public string SaveFlight(BO.Flug flug, bool force = false) { try { EFContext ctx = new EFContext(); if (force) { // Aktualisieren des Timestamps, so dass zwischenzeitliche Änderungen   // von anderen überschrieben werden var falt = ctx.Flug.AsNoTracking().SingleOrDefault(x => x.FlugNr == flug.FlugNr); ctx.Entry(flug).OriginalValues["Timestamp"] = falt.Timestamp; } ctx.Update(flug); ctx.SaveChanges(); return "OK"; } catch (Exception ex) { return "FEHLER: " + ex.ToString(); } } } }

Web-API-Dienste

Das Web-API ist mit ASP.NET Core realisiert. List-ing 2 zeigt die Implementierung der Service-Fassade mit insgesamt drei Operationen. Neben GetFlug() und PostFlug() gibt es noch eine Operation /ServerInfo, die Informationen über die Anwendungsversion und die verwendete .NET-Version liefert. Wie man sieht, besteht die Service-Fassade nur aus der Delegation an die Businesslogik (BL). Die Web-API-Infrastruktur ist hier komplett über Annotationen konfigurierbar.

Listing 2: Web Services mit ASP.NET-Core-Web-API

using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using WWWings.BL; namespace WWWings.WebAPIServices { [Produces("application/json")] [ApiController] [Route("[controller]")] public class WebAPIController : ControllerBase { [HttpGet] [Route("/Serverinfo")] public string Get() { return "WWWings Server " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + "@" + System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription; } // Beispiel-URL: http://localhost:50003/Flug/Berlin/10 [HttpGet] [Route("/Flug/{ort}/{maxcount:int=0}")] public List<WWWings.BO.Flug> GetFlug(string ort, int maxcount = 0) { return new BLManager().GetFlight(ort, maxcount); } // Beispiel-URL: http://localhost:50003/Flug?force=true [HttpPost] [Route("/Flug/")] public string PostFlug([FromBody] WWWings.BO.Flug f, [FromQuery] bool force = false) { return new BLManager().SaveFlight(f, force); } } }

In der Startup.cs-Klasse ist für das Web-API konfiguriert:

app.UseRouting(); endpoints.MapControllers();

Web-APIs mit Postman testen

Zum Testen der Web-API-Operationen kann man das kostenfreie Werkzeug Postman [2] verwenden, das beliebige HTTP-Anfragen senden kann, siehe die POST-Operation in Abbildung 1.

schwichtenberg_blazor_webservices_1.tif_fmt1.jpgAbb. 1: Web-API-Tests mit Postman

Blazor-Zugriff auf Web-APIs

Für den Zugriff auf REST-Dienste verwendet man in Blazor die in .NET Framework und .NET Core eta-blierte Bibliothek System.Net.Http.HttpClient mit der gleichnamigen Hauptklasse. Sie gehört zum Standardumfang des .NET Core SDK und muss daher in Blazor-Projekten nicht explizit als NuGet-Paket referenziert werden. Optional kann man zusätzlich auch als Hilfsbibliothek System.Net.Http.Json verwenden. Dieses Paket ist in den Blazor-WebAssembly-Projektvorlagen im Standard referenziert, in Blazor Server aber nicht. Wenn man bei der Blazor-WebAssembly-Vorlage die Option ASP.NET Core hosted auswählt, bekommt man ein Serverprojekt mit einem Web-API-REST-Dienst (/Controllers/WeatherForecastController.cs) und im Clientprojekt einen Web-API-Client (/Pages/FetchData.razor). Ohne die Option ASP.NET Core hosted erhält man eine statische JSON-Datei \wwwroot\sample-data\weather.json, die über den HTTP-Client geladen wird.

Der HTTP-Client in Blazor wird verwendet, indem man sich eine Instanz der Klasse HttpClient injizieren lässt. In der Projektvorlage für Blazor WebAssembly ist die Aufnahme dieser Klasse in den Dependency-Injection-Container in Program.cs integriert:

builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

Ab Blazor 5.0 verwendet Microsoft Folgendes:

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

In der Webseite FetchData.razor wird der HTTP-Client dann injiziert per

@inject HttpClient Http

Bis Blazor WebAssembly 3.2 Preview 3 wurde hier das spezielle NuGet-Paket Microsoft.AspNetCore.Blazor.HttpClient verwendet. Seit Preview 4 kommt das neue Zusatzpaket System.Net.Http.Json zum Einsatz, dessen Erweiterungsmethoden Microsofts neuen JSON-Serializer System.Text.Json in Verbindung mit HttpClient verwenden. Die neue Bibliothek bietet für die HTTP-Operationen GET, POST und PUT folgende Erweiterungsmethoden für die Klasse HttpClient an:

  • GetFromJsonAsync()

  • PostAsJsonAsync()

  • PutAsJsonAsync()

Es gibt jeweils mehrere Überladungen dieser drei Methoden mit folgenden Parametern:

  • URL per Zeichenkette oder Klasse System.Uri

  • Angabe des Datentyps der Nutzdaten als System.Typ oder generische Typparameter

  • Angabe von Optionen für den JSON-Serializer (JsonSerializerOptions)

  • Angabe eines ...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang