Blazor is een nieuw webframework waarmee u volledig interactieve web-apps kunt maken C# gebruiken. Met behulp van de magie van een .NET-runtime die is gecompileerd voor WebAssembly, kunt u Blazor zelfs volledig op de client uitvoeren. U hoeft geen JavaScript-frameworks meer te gebruiken om uw toepassingen te maken.
Inhoudsopgave
Wat is Blazor?
Hybride modus
Blazor instellen
Een rondleiding door de Blazor-omgeving
De vreselijke kleurkeuzes van Microsoft oplossen
Dynamische inhoud weergeven
Hoe werkt styling?
Levenscyclus van Blazor-componenten
Hoe werkt Blazor met JavaScript?< br/>Navigeren met de gebruiker door
Blazor-bibliotheken
De toekomst van Blazor
Wat is Blazor?
Blazor is de nieuwste functie van ASP.NET Core, het 20 jaar oude webframework van Microsoft. Ondanks dat het oud is, onderhoudt Microsoft het nog steeds, en ASP.NET is constant aan het verbeteren, samen met C# en de .NET-runtime als geheel.
Razor-pagina's en het oude MVC-model van ASP.NET , beide stellen u in staat om gegevensgestuurde HTML-pagina's te genereren met C#. Dat is er altijd al geweest, maar waar het altijd aan ontbrak, is interactiviteit. Het is best moeilijk om een web-app te maken als je de pagina opnieuw moet laden om wijzigingen te zien.
Dus, Blazor lost dat op door de server en client rechtstreeks te koppelen aan een bibliotheek die de DOM tijdens runtime kan wijzigen, en brengt veel van de levenscyclusmethoden van componenten en update-handlers in die je zou verwachten van een framework dat bedoeld is om mee te concurreren Reageer.
En met de minimalistische syntaxis van de Razor-pagina wordt coderen in Blazor een fluitje van een cent:
Advertentie
Blazor heeft twee hoofdmodi, de coolste waarvan Blazor Client, dat .NET zelf verpakt in een framework dat volledig op WebAssembly kan worden uitgevoerd. WASM is eigenlijk MSIL voor het web; het is een lichtgewicht binair instructieformaat waar elke taal naar kan compileren, zelfs 'desktop'. talen zoals C++ en Rust.
Dus hoe is de prestatie hiermee? Welnu, momenteel gebruikt het een tolk, aangezien er nog steeds aan de native AOT-compilatie voor .NET wordt gewerkt. Maar dat zal uiteindelijk verbeteren; het belangrijkste nadeel van Blazor Client is dat de downloadtijden langer zijn. DLL's kunnen volgens webstandaarden grote bestanden zijn, en ze moeten allemaal worden geladen om de applicatie aan de gang te krijgen. Grote JS-frameworks hebben echter ook dit probleem, en het is een belangrijke reden waarom weergave aan de serverzijde populair is.
Het compenseert die downloadtijd door zeer snel pagina's te vernieuwen en door de app te navigeren, aangezien het niet hoeft te wachten tot de server dit doet.
Als je een meer traditioneel hostingmodel wilt gebruiken, vergelijkbaar met React's Server Side Rendering (SSR), is die optie ook voor jou beschikbaar. Het is beter presterend en heeft het voordeel dat code op een vertrouwde server wordt uitgevoerd.
Om dit te bereiken, Blazor Serverkan verbinding maken met de client via een SignalR-verbinding, wat slechts een mooie wrapper over WebSockets is die ook kan terugvallen op HTTP als dat nodig is. Dit legt meer druk op de ASP.NET-server dan traditionele webhosting, omdat deze elke HTML-wijziging opnieuw moet weergeven en verzenden naar alle aangesloten clients. Als je duizenden mensen hebt aangesloten, kan dit een probleem zijn bij het opschalen.
Hoewel Blazor momenteel een webframework is, maakt Microsoft ook Blazor Desktop, dat veel op Electron lijkt door web-UI's in desktop-applicaties te verpakken, evenals Blazor Native, dat native UI's op mobiele besturingssystemen kan weergeven. Microsoft lijkt het te zien als hun volgende applicatieprogrammeermodel voor het maken van interactieve frontends op elk platform.
Hybride modus
Blazor kan ook worden gebruikt in een “hybride modus” pre-rendering gebruiken. Blazor WASM kan onbewerkte HTML weergeven terwijl het framework wordt geladen, meestal gebruikt voor een laadbalk of spinnerwiel. Maar als u de app host vanaf ASP.NET, kunt u de Razor-pagina's vanaf de server renderen voordat u de app zelfs maar naar de client verzendt.
Advertentie
Dit werkt perfect, met als nadeel dat de pagina pas interactief wordt als Blazor daadwerkelijk laadt. Het duurt echter meestal maar een seconde, dus dit is niet echt een probleem, afgezien van enkele eigenaardigheden met het twee keer herladen van gegevens.
Met deze opstelling krijg je het beste van twee werelden— je app laadt snel, zonder laadscherm, en het is razendsnel om te navigeren. Er wordt nog steeds aan deze functie gewerkt en er zijn veel eigenaardigheden, maar vanaf .NET 6 preview 6 werkt het, en je kunt meer lezen in de handleidingen van Jon Hilton, deel één en twee.
Een van de eigenaardigheden is dat WASM-apps die afhankelijk zijn van een API twee implementaties van elke service moeten hebben, op de client en de server, zodat de server met zichzelf kan praten om de informatie op te halen wanneer deze vooraf wordt weergegeven. Dit resulteert in wat knipperen wanneer WASM laadt en doet zijn eigen gegevens ophalen, maar dit kan worden opgelost in .NET 6. Deze handleiding laat zien hoe u de componentstatus kunt behouden, zodat uw app naadloos overgaat van het nep-laden pagina” naar de echte applicatie.
Blazor instellen
Gelukkig levert Visual Studio generatoren en hoeft u dit niet allemaal zelf in te stellen. Open Visual Studio en maak een nieuw project. Zoek naar “Blazor” en selecteer Blazor WebAssembly of Blazor Server.
We gaan hier voor Blazor WebAssembly, omdat Blazor Server eenvoudiger is en zowel de client als de server in hetzelfde project omvat.
Advertentie
Geef het een naam en selecteer uw framework. Een ding om op te merken is dat Blazor WebAssembly technisch gezien helemaal geen server nodig heeft; je kunt het gewoon hosten als een statische website op NGINX of zelfs een AWS S3-bucket. Maar als je verbinding maakt met een API om met een database te praten, kun je die API net zo goed gebundeld met de client maken, omdat je code tussen hen kunt delen en natuurlijk dezelfde taal kunt gebruiken.
< p>
Uw oplossing wordt opgezet met drie projecten, een clienttoepassing, een ASP.NET server-API en webhost voor de client, en een gedeelde bibliotheek daartussen.
Als u op starten klikt, ziet u dat ASP.NET wordt opgestart en de webpagina wordt weergegeven. Als u Blazor Server gebruikt, maakt deze verbinding met ASP.NET via SignalR om interacties af te handelen.
Natuurlijk zal Blazor WebAssembly alleen verzoeken naar de server sturen wanneer deze expliciet door de toepassing zijn gedaan .
Een rondleiding door de Blazor-omgeving
Laten we een rondleiding door de applicatie nemen. Beginnend met de client is het belangrijkste toegangspunt Program.cs, dat de WebAssemblyHost maakt, de rootcomponent App.razor toevoegt en vervolgens de app bouwt en uitvoert.
Technisch gezien is het toegangspunt wwwroot/index.html, dat Blazor laadt’ s JavaScript-bestand, toont een laadpagina terwijl Blazor initialiseert en geeft een foutmelding weer als dit niet het geval is.
Advertentie
App.razor verwerkt de routering van pagina's met behulp van een routercomponent. Hiermee wordt de assembly uitgevoerd en worden alle pagina's geladen die zijn gemarkeerd met het kenmerk @page name. U kunt hier meer leren over routering in Razor-pagina's.
De router laadt de MainLayout.razor-component, die LayoutComponentBase uitbreidt. Dat laadt de NavMenu.razor-component naast de body en geeft uw applicatie weer.
Super goed! Wat betreft de server, het is een standaard ASP.NET-toepassing. Het maakt een hostbuilder en voegt services toe die zijn geconfigureerd in Startup.cs. Het configureert het met name voor WASM-foutopsporing, bedient de Blazor Framework-bestanden en configureert zijn eigen Razor-pagina's en -controllers om JSON-inhoud te leveren.
Als dit slechts een Blazor Server-app was, zou het deze afzonderlijke API niet nodig hebben en zou het gewoon gegevens van een interne service kunnen ophalen. Maar aangezien dat niet het geval is, moet het die service over de draad blootleggen, in de vorm van een ASP.NET ApiController die handlermethoden specificeert voor verschillende HTTP-acties.
De modellen hiervoor worden gedeeld tussen client en server, in het gedeelde project.
p>
De vreselijke kleurkeuzes van Microsoft oplossen
Voordat we gaan coderen, moeten we iets repareren. Om de een of andere reden gebruikt Microsoft's standaardkleurkeuze voor C# HTML-richtlijnen in Razor-pagina's misschien wel de slechtst denkbare kleurencombinatie lichtpaarse tekst op een lichtbruine achtergrond.
Gelukkig jij ook. kan het wijzigen via Tools > Opties:
Advertentie
Onder Omgeving > Lettertypen en kleuren, selecteer “Razor Directive” en verander de achtergrondkleur in redelijker iets. Je wilt waarschijnlijk nog steeds dat het opvalt, dus ik heb puur zwart gekozen, wat opvalt maar niet opdringerig is.
U zult ook “HTML Server-Side Script,” (wat technisch gezien een verouderde naam is gezien het bestaan van Blazor WebAssembly).
En met die simpele oplossing kun je je ogen urenlang pijn besparen.
Dynamische inhoud presenteren
Het laatste bestand dat u wilt uitchecken, bevindt zich op de client, FetchData.razor. Dit is waar de client daadwerkelijk de server-side API gebruikt, met de volgende gegevensgestuurde pagina:
Dit is een vrij complexe Razor-pagina, dus het is een goed voorbeeld voor ons om hier uiteen te zetten.
Om te beginnen specificeert het een handmatige override voor de paginaroute met @page “/fetchdata”. Vervolgens importeert het de gedeelde modellen uit het gedeelde project en gebruikt het ook afhankelijkheidsinjectie om het een HttpClient te geven, die is ingesteld in Program.cs.
Advertentie
We gaan verder met onderaan om dit eerst uit te leggen—het @code-blok bevat de daadwerkelijke C#-code voor deze pagina. Daarin zit een privévariabele die prognoses wordt genoemd. Dit is in eerste instantie nul, maar wanneer de pagina wordt geïnitialiseerd, wordt er een webverzoek gedaan om de gegevens van de API te halen en deserialiseren.
Wanneer die variabele wordt bijgewerkt, detecteert Blazor de wijziging en wordt de pagina opnieuw weergegeven. De pagina zelf is alles daartussenin, dat begint met een koptekst en een beschrijving, maar vervolgens een @if-statement bevat. Dit is voorwaardelijke HTML in C# en wordt in dit geval gebruikt om laadtekst weer te geven terwijl Blazor het verzoek aan de API doet. Als het vervolgens is voltooid en opnieuw wordt weergegeven, zijn de prognoses niet nul en wordt de tabel weergegeven die het @foreach-element in de lijst zal doen en een tabelrij weergeeft.
Hiermee kunt u dynamische inhoud van uw modellen renderen. Om meer geavanceerde CRUD-bewerkingen en meer dynamische gebruikersinterfaces te ondersteunen, moet u knoppen en invoer gebruiken. U kunt <button> tags met een @onclick kenmerk, waarvoor een methodeverwijzing nodig is.
< p>U kunt EventCallbacks gebruiken om de gebeurtenis door te geven aan bovenliggende componenten. U kunt ook Lambda-expressies gebruiken om gebeurtenissen inline af te handelen, als de methode kort is:
<button @onclick=”@(e => rubriek = “Nieuwe kop!!!”)”> Kopje bijwerken </button>
Er zijn meerdere aanvullende gebeurtenisargumenten die u aan deze handlerfuncties kunt doorgeven, waaronder muislocatie, toetsenbordgebeurtenissen en aanraakgebeurtenissen.
Als u een zoekvak wilt implementeren, heeft Blazor daarvoor bindingen. Als u echter wilt dat het automatisch zoekt wanneer u op enter drukt, en niet bij elke toetsaanslag, moet u de @onkeydown-gebeurtenis binden aan een functie, die een KeyboardEventArgs-object nodig heeft, en handmatig controleren of Enter is ingedrukt.
Advertentie
U kunt de invoerwaarde echter niet uit de KeyboardEventArgs halen, dus het resulteert in dit rommelige invoervak waar u onkeydown en oninput moet binden, een tekenreekswaarde moet instellen en die tekenreeks vervolgens in onkeydown moet gebruiken.
< 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 } } }
Hoe werkt styling?
Extreem eenvoudig. Er is een site.css-hoofdbestand, maar voor de styling op componentniveau maakt u gewoon een .razor.css-bestand voor elke Razor-pagina:
index.razor index.razor.css
Blazor maakt automatisch een scoped CSS-bestand dat de instellingen van elke Razor-pagina toepast op alleen die Razor-pagina:
<link href=”BlazorWebAssemblyTest.Client.styles.css” rel=”stylesheet” /> /* /Pages/Counter.razor.rz.scp.css */h1[b-3xxtam6d07] { kleur: bruin; }
Pre-processors zoals SASS aan het werk krijgen is iets ingewikkelder, maar volledig uitvoerbaar.
Blazor Component Lifecycle
Zoals React, Blazor heeft ook component lifecycle bindingen. Volgens dit diagram van Blazor University, een fantastische bron om Blazor te leren, roept de Blazor-runtime ze in de volgende volgorde aan:
SetParametersAsync en OnParametersSet worden aangeroepen wanneer de bovenliggende component van de component wordt weergegeven. OnInitializedAsync wordt hier ook genoemd als het de eerste keer is. Vervolgens kan de gebeurtenis voor elke gebruikersinteractie StateHasChanged aanroepen, die controleert of deze moet worden weergegeven, en dit updateproces opnieuw activeert.
Advertentie
Er zijn te veel details om hier op te sommen, dus lees de gids van Blazor University, die ze allemaal uitlegt, evenals vreemde interacties met async/wait-methoden. Om zoveel mogelijk inhoud zo snel mogelijk weer te geven, kan Blazor StateHasChanged uitvoeren en twee keer renderen, één keer goed wanneer het Task waiter-object wordt geretourneerd en één keer wanneer het klaar is.
Hoe werkt Blazor met JavaScript?
Ongeacht of u Blazor Server of Blazor Desktop gebruikt, u beschikt over volledige JavaScript-interoperabiliteit, zoals het aanroepen van JS-functies vanuit beheerde code:
private async Taak ConvertArray() {text = new(wacht op JS.InvokeAsync<string>(“convertArray”, quoteArray)); }
En .NET aanroepen vanuit JS:
DotNet.invokeMethodAsync('{ASSEMBLY NAME}', '{.NET METHOD ID}', {ARGUMENTS});
Je kunt eigenlijk alle NPM-pakketten met Blazor gebruiken, hoewel je meestal de voorkeur geeft aan een NuGet-pakket als dat een optie is.
Navigeren door de gebruiker
Een van de belangrijkste problemen met web-apps, met name single-page web-apps (SPWA's), is routering. Elke Razor-pagina heeft een standaardroute volgens de naam, maar u kunt deze overschrijven en u kunt ook meerdere paginaroutes toevoegen aan elke Razor-pagina. De router zal elk afzonderlijk matchen en nog steeds hetzelfde bestand dienen.
Als u echter verschillende inhoud wilt weergeven, afhankelijk van de URL waarop u zich bevindt, wordt het een beetje ingewikkeld. De eenvoudigste oplossing zou zijn om een @page-route te definiëren voor elke string die u wilt toevoegen. Dit werkt de eerste keer, maar vanwege de manier waarop Blazor met updates omgaat, wordt de pagina niet vernieuwd wanneer naar een nieuwe URL wordt genavigeerd, omdat de parameters niet zijn gewijzigd. Je kunt dit nog steeds gebruiken om meerdere spellingen van dezelfde pagina te definiëren, zolang die pagina's niet naar elkaar linken.
De oplossing voor het SPWA-probleem is om op parameters gebaseerde routes te gebruiken wanneer je maar wilt. meerdere opties wilt vangen en daartussen wilt koppelen. Parameters kunnen tussen haakjes worden gedefinieerd:
Advertentie
Deze specifieke opstelling is voor de hoofdpagina. Als je bang bent dat het zal overeenkomen met andere pagina's zoals /error, omdat het is geconfigureerd om iets na root te matchen, maak je geen zorgen, Blazor zal overeenkomen met andere pagina's die strikt zijn gedefinieerd alvorens terug te vallen op het gebruik van op parameters gebaseerde routes. U kunt echter niet meerdere parameterroutes op dezelfde rootroute hebben zonder een dubbelzinnige routefout te krijgen.
In mijn geval wilde ik de gebruiker met een argument naar een nieuwe pagina navigeren. U kunt dit doen door naar de NavigationManager te gaan en NavigateTo:
NavManager.NavigateTo(“/search/” + searchValue);
Als u meer geavanceerde routering wilt, moet u de queryparameters bekijken.
Handmatig de pagina bijwerken bij URL-wijziging
Een van de eigenaardigheden van Blazor is dat het geen update activeert wanneer je URL verandert, zelfs als je stateful code hebt die ervan afhankelijk is, dus je zult handmatig moeten updaten. Gelukkig heeft de NavigationManager een gemachtigde voor wanneer de locatie verandert, en je kunt daar een functie aan binden.
NavigationManager.LocationChanged += HandleLocationChanged;
U wilt InvokeAsync gebruiken met een functie die het statusobject bijwerkt waarvan uw app afhankelijk is. Daarna moet u StateHasChanged aanroepen om een vernieuwing te activeren.
Je kunt vanaf hier ook OnParametersSetAsync aanroepen, als je code ook afhankelijk is van andere URL-parameters en je niet wilt kopiëren/plakken.
Blazor Bibliotheken
Een van de voordelen van Blazor is dat het niet iets nieuws is, het is gebouwd op de 20-jarige ruggengraat van ASP.NET, en dus wordt het al geleverd met een divers ecosysteem van bibliotheken. We zullen ze hier niet op een lijst zetten, omdat er al een geweldige lijst is op GitHub die alles dekt.
Advertentie
Echter, één ding moet je zeker doen worden gebruikt is een vooraf gemaakte componentenbibliotheek. Er zijn een paar gratis, maar RadZen is een van de meest populaire en het is volledig open source. Blazorise is ook een geweldige, hoewel het alleen gratis is voor niet-commerciële producten.
In beide gevallen zal het gebruik van kant-en-klare componentlay-outs en deze later met de hand te stylen, snelle prototyping mogelijk maken en uw ontwikkelingstijd drastisch versnellen. We raden ze ten zeerste aan.
De toekomst van Blazor
Blazor is een werkelijk uniek framework tussen een oceaan van op JavaScript gebaseerde React-klonen, en met Microsoft erachter heeft het een mooie toekomst. We hebben eerder vermeld dat Microsoft plannen had voor Blazor Desktop, die eind 2021 uitkomt.
Blazor Desktop zal net zo werken als Electron, waar het je app start in een Chromium-container met enkele bindingen voor desktopfunctionaliteit . Maar in plaats van Chromium te gebruiken, gaat Blazor Desktop native gebaseerde WebViews gebruiken en de .NET-code rechtstreeks op de machine uitvoeren.
In de tussentijd kun je Blazor nu daadwerkelijk op de desktop krijgen met Electron .NET, en het werkt verrassend goed. Het enige wat u hoeft te doen is het te installeren en Electron toe te voegen als een ASP.NET-service. Je kunt Electron-native functies ook aanroepen vanuit C#.