Blazor ist ein neues Web-Framework, mit dem Sie vollständig interaktive Web-Apps erstellen können C# verwenden. Mit der Magie einer für WebAssembly kompilierten .NET-Laufzeit können Sie Blazor sogar vollständig auf dem Client ausführen.—Sie müssen keine JavaScript-Frameworks mehr verwenden, um Ihre Anwendungen zu erstellen.
Inhaltsverzeichnis
Was ist Blazor?
Hybrid-Modus
Blazor einrichten
Eine Tour durch die Blazor-Umgebung
Beheben der schrecklichen Farbauswahl von Microsoft
Bereitstellen dynamischer Inhalte
Wie funktioniert das Styling?
Blazor-Komponentenlebenszyklus
Wie funktioniert Blazor mit JavaScript?< br/>Navigieren des Benutzers durch
Blazor-Bibliotheken
Die Zukunft von Blazor
Was ist Blazor?
Blazor ist die neueste Funktion von ASP.NET Core, dem 20 Jahre alten Web-Framework von Microsoft. Obwohl es alt ist, pflegt Microsoft es immer noch, und ASP.NET wurde zusammen mit C# und der .NET-Runtime als Ganzes ständig verbessert.
Razor-Seiten und das alte MVC-Modell von ASP.NET , ermöglichen Ihnen beide das Generieren von datengesteuerten HTML-Seiten mit C#. Das gibt es schon ewig, aber was ihm immer gefehlt hat, ist Interaktivität. Es ist ziemlich schwierig, eine Web-App zu erstellen, wenn Sie die Seite neu laden müssen, um Änderungen anzuzeigen.
Blazor löst dies also, indem es den Server und den Client direkt mit einer Bibliothek verknüpft, die das DOM zur Laufzeit ändern kann, und bringt viele der Komponentenlebenszyklusmethoden und Update-Handler ein, die Sie von einem Framework erwarten würden, mit dem es konkurrieren soll Reagieren.
Und mit der minimalistischen Syntax der Razor-Seite wird das Codieren in Blazor zum Kinderspiel:
Werbung
Blazor hat zwei Hauptbetriebsmodi, den coolsten davon Blazor-Client, das .NET selbst in ein Framework verpackt, das vollständig auf WebAssembly ausgeführt werden kann. WASM ist im Grunde MSIL für das Web; Es ist ein einfaches binäres Befehlsformat, in das jede Sprache kompilieren kann, sogar “Desktop” Sprachen wie C++ und Rust.
Wie ist die Leistung damit? Nun, derzeit verwendet es einen Interpreter, da an der nativen AOT-Kompilierung für .NET noch gearbeitet wird. Aber das wird sich irgendwann verbessern; Der Hauptnachteil von Blazor Client sind längere Downloadzeiten&8212;DLLs können nach Webstandards große Dateien sein, und sie müssen alle geladen werden, um die Anwendung zum Laufen zu bringen. Allerdings haben auch große JS-Frameworks dieses Problem und es ist ein wichtiger Grund, warum serverseitiges Rendering so beliebt ist.
Es gleicht diese Downloadzeit aus, indem es sehr schnell Seiten aktualisiert und in der App navigiert. wenn man bedenkt, dass es nicht warten muss, bis der Server dies tut.
< /p>
Wenn Sie ein traditionelleres Hosting-Modell verwenden möchten, das dem Server Side Rendering (SSR) von React ähnelt, steht Ihnen diese Option ebenfalls zur Verfügung. Es ist leistungsfähiger und bietet den Vorteil, dass Code auf einem vertrauenswürdigen Server ausgeführt wird.
Um dies zu erreichen, Blazor Serverkann sich über eine SignalR-Verbindung mit dem Client verbinden, die nur ein schicker Wrapper über WebSockets ist, der bei Bedarf auch auf HTTP zurückgreifen kann. Dies belastet den ASP.NET-Server stärker als herkömmliches Webhosting, da er jede einzelne HTML-Änderung neu rendern und an alle verbundenen Clients senden muss. Wenn Tausende von Personen verbunden sind, kann dies beim Hochskalieren ein Problem sein.
< /p>
Während Blazor derzeit ein Web-Framework ist, stellt Microsoft auch Blazor Desktop her, das ähnlich wie Electron funktioniert, indem es Web-UIs in Desktop-Anwendungen verpackt, sowie Blazor Native, das in der Lage sein wird, native UIs auf mobilen Betriebssystemen zu rendern. Microsoft scheint es als ihr nächstes Anwendungsprogrammiermodell für die Erstellung interaktiver Frontends auf jeder Plattform zu betrachten.
Hybrid-Modus
Blazor can auch im “Hybrid-Modus” Vorrendern verwenden. Blazor WASM kann rohes HTML anzeigen, während das Framework geladen wird, was normalerweise für eine Ladeleiste oder ein Spinnerrad verwendet wird. Wenn Sie die App jedoch über ASP.NET hosten, können Sie die Razor-Seiten vom Server rendern, bevor Sie die App überhaupt an den Client senden.
Werbung
Dies funktioniert perfekt, mit dem Haken, dass die Seite erst interaktiv wird, wenn Blazor tatsächlich geladen wird. Es dauert jedoch normalerweise nur eine Sekunde, daher ist dies kein wirkliches Problem, abgesehen von einigen Macken beim zweimaligen Neuladen von Daten.
Mit diesem Setup erhalten Sie das Beste aus beiden Welten— Ihre App wird schnell geladen, ohne Ladebildschirm, und die Navigation ist blitzschnell. An dieser Funktion wird noch gearbeitet und sie hat viele Macken, aber ab .NET 6-Vorschau 6 funktioniert sie, und Sie können mehr in Jon Hiltons Leitfäden, Teil 1 und 2, lesen.
Eine der Eigenheiten besteht darin, dass WASM-Apps, die auf einer API basieren, zwei Implementierungen jedes Dienstes auf dem Client und dem Server haben müssen, damit der Server mit sich selbst kommunizieren kann, um die Informationen beim Vorrendern abzurufen. Dies führt zu einem gewissen Blinken, wenn WASM lädt und seinen eigenen Datenabruf durchführt, aber dies kann in .NET 6 behoben werden—diese Anleitung zeigt, wie der Komponentenstatus beibehalten wird, damit Ihre App nahtlos vom gefälschten “Laden . übergeht Seite” zur realen Anwendung.
Blazor einrichten
Zum Glück stellt Visual Studio Generatoren bereit und Sie müssen dies nicht alles selbst einrichten. Öffnen Sie Visual Studio, und erstellen Sie ein neues Projekt. Suchen Sie nach “Blazor” und wählen Sie entweder Blazor WebAssembly oder Blazor Server.
Wir werden hier Blazor WebAssembly verwenden, da Blazor Server einfacher ist und sowohl den Client als auch den Server im selben Projekt umfasst.
Werbung
Geben Sie ihm einen Namen und wählen Sie Ihr Framework aus. Zu beachten ist, dass Blazor WebAssembly technisch gesehen nicht einmal einen Server benötigt; Sie können es einfach als statische Website auf NGINX oder sogar als AWS S3-Bucket hosten. Wenn Sie jedoch eine Verbindung zu einer API herstellen, um mit einer Datenbank zu kommunizieren, können Sie diese API genauso gut mit dem Client bündeln, da Sie Code zwischen ihnen austauschen und natürlich dieselbe Sprache verwenden können.
< p>
Ihre Lösung wird mit drei Projekten, einer Client-Anwendung, einem ASP.NET . eingerichtet Server-API und Webhost für den Client sowie eine gemeinsame Bibliothek zwischen ihnen.
Wenn Sie auf Starten klicken, wird ASP.NET gestartet und die Webseite bereitgestellt. Wenn Sie Blazor Server verwenden, wird eine Verbindung zu ASP.NET über SignalR hergestellt, um Interaktionen zu verarbeiten.
Natürlich sendet Blazor WebAssembly nur Anfragen an den Server, wenn diese explizit von der Anwendung gestellt werden .
Eine Tour durch die Blazor-Umgebung
Lassen Sie uns eine Tour durch die Anwendung machen. Beginnend mit dem Client ist der Haupteinstiegspunkt Program.cs, das den WebAssemblyHost erstellt, die Stammkomponente App.razor hinzufügt und dann die App erstellt und ausführt.
Technisch gesehen ist der Einstiegspunkt wwwroot/index.html, der Blazor lädt’ s JavaScript-Datei, zeigt eine Ladeseite an, während Blazor initialisiert wird, und zeigt eine Fehlermeldung an, wenn dies nicht der Fall ist.
Werbung
App.razor verarbeitet das Routing von Seiten mithilfe einer Router-Komponente. Dadurch wird die Assembly aufgenommen und alle Seiten geladen, die mit dem Attribut @page name markiert sind. Weitere Informationen zum Routing auf Razor-Seiten finden Sie hier.
Der Router lädt die Komponente MainLayout.razor, die LayoutComponentBase erweitert. Dadurch wird die NavMenu.razor-Komponente neben dem Körper geladen und Ihre Anwendung angezeigt.
Groß! Der Server ist eine Standard-ASP.NET-Anwendung. Es erstellt einen Host-Builder und fügt Dienste hinzu, die in Startup.cs konfiguriert sind. Insbesondere wird es für das WASM-Debugging konfiguriert, die Blazor-Framework-Dateien bereitgestellt und seine eigenen Razor-Seiten und -Controller konfiguriert, um JSON-Inhalte bereitzustellen.
Wenn dies nur eine Blazor Server-App wäre, würde sie diese separate API nicht benötigen und könnte einfach Daten von einem internen Dienst abrufen. Da dies jedoch nicht der Fall ist, muss dieser Dienst über die Leitung in Form eines ASP.NET ApiControllers bereitgestellt werden, der Handlermethoden für verschiedene HTTP-Aktionen angibt.
Die Modelle dafür werden zwischen Client und Server im gemeinsamen Projekt geteilt.
Behebung der schrecklichen Farbauswahl von Microsoft
Bevor wir uns an den Code setzen, müssen wir etwas reparieren. Aus irgendeinem Grund verwendet Microsofts Standardfarbauswahl für C#-HTML-Anweisungen auf Razor-Seiten die vielleicht schlechteste Farbkombination, die man sich vorstellen kann: hellvioletter Text auf hellbraunem Hintergrund.
Zum Glück kann es über Extras > Optionen:
Werbung
Unter Umgebung > Schriftarten und Farben, wählen Sie “Razor-Richtlinie” und ändern Sie die Hintergrundfarbe in etwas vernünftigeres. Sie möchten wahrscheinlich immer noch, dass es auffällt, also habe ich einfach reines Schwarz gewählt, das auffällig, aber nicht aufdringlich ist.
Sie müssen auch “HTML Server-Side Script,” (was technisch gesehen ein veralteter Name ist, wenn man die Existenz von Blazor WebAssembly bedenkt).
Und mit dieser einfachen Lösung können Sie Ihren Augen stundenlange Schmerzen ersparen.
Dynamische Inhalte bereitstellen
Die letzte Datei, die Sie auschecken möchten, befindet sich auf dem Client, FetchData.razor. Hier nutzt der Client tatsächlich die serverseitige API mit der folgenden datengesteuerten Seite:
Dies ist eine ziemlich komplexe Razor-Seite, daher ist es ein gutes Beispiel für uns, hier aufzubrechen.
Zu Beginn gibt es mit @page “/fetchdata” eine manuelle Überschreibung für die Seitenroute an. Es importiert dann die freigegebenen Modelle aus dem freigegebenen Projekt und verwendet Dependency Injection, um ihm einen HttpClient zu geben, der in Program.cs eingerichtet wurde.
Werbung
Wir gehen weiter zu unten, um dies zuerst zu erklären—der @code-Block enthält den eigentlichen C#-Code für diese Seite. Darin befindet sich eine private Variable namens Prognosen. Dies ist anfänglich null, aber wenn die Seite initialisiert wird, stellt sie eine Webanfrage, um die Daten aus der API zu holen und sie zu deserialisieren.
Wenn diese Variable aktualisiert wird, erkennt Blazor die Änderung und rendert die Seite neu. Die Seite selbst ist alles dazwischen, was mit einer Kopfzeile und einer Beschreibung beginnt, dann aber eine @if-Anweisung enthält. Dies ist bedingtes C#-HTML und wird in diesem Fall verwendet, um Ladetext anzuzeigen, während Blazor die Anforderung an die API stellt. Wenn es dann fertig ist und neu gerendert wird, sind die Prognosen nicht null und es wird die Tabelle rendern, die das @foreach-Element in der Liste ausführt, und eine Tabellenzeile rendern.
Auf diese Weise können Sie dynamische Inhalte aus Ihren Modellen rendern. Um erweiterte CRUD-Operationen und dynamischere Benutzeroberflächen zu unterstützen, müssen Sie Schaltflächen und Eingaben verwenden. Sie können die <Schaltfläche> Tags mit einem @onclick Attribut, das eine Methodenreferenz benötigt.
< p>Sie können EventCallbacks verwenden, um das Ereignis an übergeordnete Komponenten weiterzugeben. Sie können auch Lambda-Ausdrücke verwenden, um Ereignisse inline zu behandeln, wenn die Methode kurz ist:
<button @onclick=”@(e => header = “Neue Überschrift!!!”)”> Überschrift aktualisieren </button>
Es gibt mehrere zusätzliche Ereignisargumente, die Sie an diese Handlerfunktionen übergeben können, einschließlich Mausposition, Tastaturereignisse und Berührungsereignisse.
Wenn Sie ein Suchfeld implementieren möchten, bietet Blazor Bindungen dafür. Wenn Sie jedoch möchten, dass automatisch beim Drücken der Eingabetaste und nicht bei jedem Tastendruck gesucht wird, müssen Sie das @onkeydown-Ereignis an eine Funktion binden, die ein KeyboardEventArgs-Objekt akzeptiert, und manuell überprüfen, ob die Eingabetaste gedrückt wurde.
Werbung
Sie können den Eingabewert jedoch nicht aus den KeyboardEventArgs abrufen. Dies führt zu diesem unübersichtlichen Eingabefeld, in dem Sie onkeydown und oninput binden, einen Stringwert festlegen und diesen String dann in onkeydown verwenden müssen.
< input type=”text” @onkeydown=”@Enter” @oninput=”@(ui => { searchValue = (string) ui.Value;})” /> @code { public void Enter(KeyboardEventArgs e) { if (e.Code == “Enter” || e.Code == “NumpadEnter”) { //do stuff } } }
Wie funktioniert das Styling?
Extrem einfach. Es gibt zwar eine site.css-Masterdatei, aber für das Styling auf Komponentenebene erstellen Sie einfach eine .razor.css-Datei für jede Razor-Seite:
index.razor index.razor.css
Blazor erstellt automatisch eine CSS-Datei mit Geltungsbereich, die die Einstellungen von jeder Razor-Seite nur auf diese Razor-Seite anwendet:
<link href=”BlazorWebAssemblyTest.Client.styles.css” rel=”stylesheet” /> /* /Pages/Counter.razor.rz.scp.css */h1[b-3xxtam6d07] { Farbe: braun; }
Präprozessoren wie SASS zum Laufen zu bringen ist etwas komplizierter, aber durchaus machbar.
Blazor-Komponentenlebenszyklus
Wie React, Blazor verfügt auch über Komponentenlebenszyklusbindungen. Gemäß diesem Diagramm der Blazor University, einer fantastischen Ressource zum Erlernen von Blazor, ruft die Blazor-Laufzeit sie in der folgenden Reihenfolge auf:
SetParametersAsync und OnParametersSet werden immer dann aufgerufen, wenn das übergeordnete Element der Komponente gerendert wird. OnInitializedAsync wird hier auch aufgerufen, wenn es das erste Mal ist. Dann kann das Ereignis für jede Benutzerinteraktion StateHasChanged aufrufen, das überprüft, ob es gerendert werden soll, und diesen Aktualisierungsprozess erneut auslöst.
Werbung
Es gibt zu viele Details, um sie hier aufzulisten, daher sollten Sie den Leitfaden der Blazor University lesen, der alle erklärt, sowie seltsame Interaktionen mit async/await-Methoden. Um so viel Inhalt so schnell wie möglich zu rendern, kann Blazor StateHasChanged ausführen und zweimal rendern, einmal direkt, wenn das Task-Awaiter-Objekt zurückgegeben wird, und einmal, wenn es fertig ist.
Wie funktioniert Blazor mit JavaScript?
Unabhängig davon, ob Sie Blazor Server oder Blazor Desktop verwenden, haben Sie vollständige JavaScript-Interoperabilität, z. B. das Aufrufen von JS-Funktionen aus verwaltetem Code:
private asynchrone Aufgabe ConvertArray() { text = new(wait JS.InvokeAsync<string>(“convertArray”, quoteArray)); }
Und Aufrufen von .NET aus JS:
DotNet.invokeMethodAsync('{ASSEMBLY NAME}', '{.NET METHOD ID}', {ARGUMENTS});
Sie können tatsächlich alle NPM-Pakete mit Blazor verwenden, obwohl Sie meistens ein NuGet-Paket bevorzugen sollten, wenn dies eine Option ist.
Durch den Benutzer navigieren
Eines der wichtigsten Probleme bei Web-Apps, insbesondere bei Single-Page-Web-Apps (SPWAs), ist das Routing. Jede Razor-Seite hat entsprechend ihrem Namen eine Standardroute, die Sie jedoch überschreiben können, und Sie können jeder Razor-Seite auch mehrere Seitenrouten hinzufügen. Der Router vergleicht jeden einzeln und liefert immer noch dieselbe Datei.
Wenn Sie jedoch je nach URL unterschiedliche Inhalte bereitstellen möchten, wird die Sache etwas kompliziert. Die einfachste Lösung wäre, für jede Zeichenfolge, die Sie hinzufügen möchten, eine @page-Route zu definieren. Dies funktioniert beim ersten Mal, aber aufgrund der Art und Weise, wie Blazor mit Updates umgeht, wird die Seite beim Navigieren zu einer neuen URL nicht aktualisiert, da sich die Parameter nicht geändert haben. Sie können dies immer noch verwenden, um mehrere Schreibweisen derselben Seite zu definieren, solange diese Seiten nicht miteinander verlinkt sind.
Die Lösung des SPWA-Problems besteht darin, parameterbasierte Routen zu verwenden, wenn Sie mehrere Optionen erfassen und zwischen ihnen verknüpfen möchten. Parameter können in Klammern definiert werden:
Werbung
Dieses spezielle Setup ist für die Stammseite. Wenn Sie befürchten, dass es mit anderen Seiten wie /error übereinstimmt, da es so konfiguriert ist, dass es mit allem nach root übereinstimmt, machen Sie sich keine Sorgen, Blazor wird anderen Seiten entsprechen, die streng definiert sind bevor Sie wieder auf parameterbasierte Routen zurückgreifen. Sie können jedoch nicht mehrere Parameterrouten auf derselben Stammroute haben, ohne einen mehrdeutigen Routenfehler zu erhalten.
In meinem Fall wollte ich den Benutzer mit einem Argument zu einer neuen Seite navigieren. Sie können dies tun, indem Sie auf den NavigationManager zugreifen und NavigateTo aufrufen:
NavManager.NavigateTo(“/search/” + searchValue);
Wenn Sie ein erweitertes Routing wünschen, müssen Sie sich die Abfrageparameter ansehen.
Manuelles Aktualisieren der Seite bei URL-Änderung
Eine der Eigenheiten von Blazor besteht darin, dass es kein Update auslöst, wenn sich Ihre URL ändert, selbst wenn Sie Stateful-Code haben, der davon abhängt. Sie müssen also manuell aktualisieren. Glücklicherweise hat der NavigationManager einen Stellvertreter für die Änderung des Standorts, an den Sie eine Funktion binden können.
NavigationManager.LocationChanged += HandleLocationChanged;
Sie möchten InvokeAsync mit einer Funktion verwenden, die das Statusobjekt aktualisiert, von dem Ihre App abhängt. Anschließend müssen Sie StateHasChanged aufrufen, um eine Aktualisierung auszulösen.
< /p>
Sie können auch OnParametersSetAsync von hier aus aufrufen, wenn Ihr Code auch von anderen URL-Parametern abhängt und Sie nicht kopieren/einfügen möchten.
Blazor Bibliotheken
Einer der Vorteile von Blazor ist, dass es keine brandneue Sache ist, sondern auf dem 20-jährigen Backbone von ASP.NET aufbaut und daher bereits über ein vielfältiges Ökosystem von Bibliotheken verfügt. Wir werden hier nicht auf eine Liste von ihnen eingehen, denn auf GitHub gibt es bereits die awesome-blazor-Liste, die alles abdeckt.
Werbung
Eines solltet ihr jedoch unbedingt be using ist eine vorgefertigte Komponentenbibliothek. Es gibt ein paar kostenlose, aber RadZen ist eines der beliebtesten und vollständig Open Source. Blazorise ist ein weiteres großartiges Produkt, obwohl es nur für nicht-kommerzielle Produkte kostenlos ist.
In jedem Fall ermöglicht die Verwendung vorgefertigter Komponentenlayouts und deren spätere manuelle Gestaltung ein schnelles Prototyping und beschleunigt Ihre Entwicklungszeit drastisch. Wir empfehlen sie wärmstens.
Die Zukunft von Blazor
Blazor ist ein wirklich einzigartiges Framework unter einem Ozean von JavaScript-basierten React-Klonen, und mit Microsoft dahinter hat es eine glänzende Zukunft. Wir haben bereits erwähnt, dass Microsoft Pläne für Blazor Desktop hatte, das Ende 2021 erscheinen wird.
Blazor Desktop wird ähnlich wie Electron funktionieren, wo es Ihre App in einem Chromium-Container mit einigen Bindungen für die Desktop-Funktionalität startet . Anstatt Chromium zu verwenden, verwendet Blazor Desktop jedoch native basierte WebViews und führt den .NET-Code direkt auf dem Computer aus.
In der Zwischenzeit können Sie Blazor jetzt tatsächlich mit Electron auf dem Desktop installieren .NET, und es funktioniert überraschend gut. Sie müssen es nur installieren und Electron als ASP.NET-Dienst hinzufügen. Sie können auch native Electron-Funktionen aus C# aufrufen.