Comment créer des applications Web clientes C# avec le framework Web Blazor de Microsoft

Blazor est un nouveau framework Web qui vous permet de créer des applications Web entièrement interactives à l'aide de C#. En utilisant la magie d'un runtime .NET compilé pour WebAssembly, vous pouvez même exécuter Blazor entièrement sur le client, vous n'avez plus besoin d'utiliser des frameworks JavaScript pour créer vos applications.

Table des matières

Qu'est-ce que Blazor ?
Mode hybride
Configuration de Blazor
Une visite guidée de l'environnement Blazor< br/>Correction des choix de couleurs horribles de Microsoft
Servir du contenu dynamique
Comment fonctionne le style ?
Cycle de vie des composants Blazor
Comment Blazor fonctionne-t-il avec JavaScript ?
Naviguer l'utilisateur autour
Bibliothèques Blazor
L'avenir de Blazor

Qu'est-ce que Blazor ?

Blazor est la dernière fonctionnalité d'ASP.NET Core, le framework Web de Microsoft datant de 20 ans. Bien qu'il soit ancien, Microsoft le maintient toujours et ASP.NET s'est constamment amélioré avec C# et le runtime .NET dans son ensemble.

Les pages Razor et l'ancien modèle MVC d'ASP.NET , les deux vous permettent de générer des pages HTML basées sur les données à l'aide de C#. Cela existe depuis toujours, mais ce qui lui manque toujours, c'est l'interactivité. Il est assez difficile de créer une application Web lorsque vous devez recharger la page pour afficher les modifications.

Ainsi, Blazor résout cela en liant directement le serveur et le client avec une bibliothèque qui peut modifier le DOM au moment de l'exécution, et apporte de nombreuses méthodes de cycle de vie des composants et des gestionnaires de mise à jour que vous attendez d'un framework destiné à rivaliser avec Réagissez.

Et, avec la syntaxe minimaliste de la page Razor, le codage dans Blazor est un jeu d'enfant :

Publicité

Blazor a deux modes de fonctionnement principaux, le plus cool dont Client Blazor, qui emballe .NET lui-même dans un framework pouvant être exécuté entièrement sur WebAssembly. WASM est essentiellement MSIL pour le Web ; il s'agit d'un format d'instruction binaire léger vers lequel n'importe quel langage peut compiler, même “desktop” langages comme C++ et Rust.

Alors, comment sont les performances avec cela? Eh bien, actuellement, il utilise un interpréteur, car la compilation AOT native pour .NET est toujours en cours de travail. Mais cela finira par s'améliorer; Le principal inconvénient de Blazor Client est que les temps de téléchargement sont plus longs. Les DLL peuvent être de gros fichiers selon les normes Web, et elles doivent toutes être chargées pour que l'application soit opérationnelle. Cependant, les grands frameworks JS ont également ce problème, et c'est l'une des principales raisons pour lesquelles le rendu côté serveur est populaire.

Il compense le temps de téléchargement en étant très rapide pour actualiser les pages et naviguer dans l'application, étant donné qu'il n'est pas nécessaire d'attendre que le serveur le fasse.

Si vous souhaitez utiliser un modèle d'hébergement plus traditionnel similaire au rendu côté serveur (SSR) de React, cette option est également disponible. Il est plus performant et présente l'avantage d'exécuter du code sur un serveur de confiance.

Pour y parvenir, Blazor Serverpeut se connecter au client à l'aide d'une connexion SignalR, qui n'est qu'un wrapper sophistiqué sur WebSockets qui peut également se rabattre sur HTTP si nécessaire. Cela met plus de pression sur le serveur ASP.NET que l'hébergement Web traditionnel, car il doit restituer et renvoyer chaque modification HTML à tous les clients connectés. Si vous avez des milliers de personnes connectées, cela peut être un problème lors de la mise à l'échelle.

Alors que Blazor est actuellement un framework Web, Microsoft crée également Blazor Desktop, qui fonctionne un peu comme Electron en empaquetant des interfaces utilisateur Web dans des applications de bureau, ainsi que Blazor Native, qui sera capable de restituer des interfaces utilisateur natives sur des systèmes d'exploitation mobiles. Microsoft semble le considérer comme son prochain modèle de programmation d'applications pour créer des interfaces interactives sur n'importe quelle plate-forme.

Mode hybride

Blazor peut également être utilisé en “mode hybride” en utilisant le pré-rendu. Blazor WASM peut afficher du HTML brut pendant le chargement du framework, généralement utilisé pour une barre de chargement ou une roue tournante. Mais, si vous hébergez l'application depuis ASP.NET, vous pouvez afficher les pages Razor depuis le serveur avant même d'envoyer l'application au client.

Publicité

Cela fonctionne parfaitement, avec le piège que la page ne deviendra pas interactive tant que Blazor ne se chargera pas réellement. Cela ne prend généralement qu'une seconde, donc ce n'est pas vraiment un problème, à part quelques bizarreries avec le rechargement des données deux fois.

Avec cette configuration, vous obtenez le meilleur des deux mondes— votre application se charge rapidement, sans écran de chargement, et sa navigation est ultra-rapide. Cette fonctionnalité est toujours en cours d'élaboration et comporte de nombreuses bizarreries, mais à partir de l'aperçu .NET 6 6, elle fonctionne et vous pouvez en savoir plus sur les guides de Jon Hilton, parties un et deux.

L'une des bizarreries est que les applications WASM reposant sur une API devront avoir deux implémentations de chaque service, sur le client et le serveur, afin que le serveur puisse se parler pour récupérer les informations lors du pré-rendu. Cela se traduit par un certain clignotement lorsque WASM se charge et effectue sa propre récupération de données, mais cela peut être corrigé dans .NET 6—ce guide montre comment conserver l'état du composant afin que votre application passe en toute transparence du faux “chargement page” à l'application réelle.

Configuration de Blazor

Heureusement, Visual Studio fournit des générateurs et vous n'avez pas besoin de les définir tout toi-même. Ouvrez Visual Studio et créez un nouveau projet. Recherchez “Blazor” et sélectionnez Blazor WebAssembly ou Blazor Server.

Nous allons utiliser Blazor WebAssembly ici, car Blazor Server est plus simple et inclut à la fois le client et le serveur dans le même projet.

Publicité

Donnez-lui un nom et sélectionnez votre framework. Une chose à noter est que Blazor WebAssembly n'a techniquement même pas besoin d'un serveur du tout; vous pouvez simplement l'héberger en tant que site Web statique sur NGINX ou même un compartiment AWS S3. Mais, si vous vous connectez à une API pour parler à une base de données, vous pouvez aussi bien intégrer cette API au client, car vous pouvez partager du code entre eux et bien sûr utiliser le même langage.

< p>

Votre solution sera configurée avec trois projets, une application cliente, une API serveur ASP.NET et un hébergeur web pour le client, et une bibliothèque partagée entre eux.

Si vous cliquez sur Lancer, vous verrez ASP.NET démarrer et servir la page Web. Si vous utilisez Blazor Server, il se connectera à ASP.NET via SignalR pour gérer les interactions.

Bien sûr, Blazor WebAssembly n'enverra des requêtes au serveur que lorsqu'elles sont explicitement faites par l'application.

Une visite guidée de l'environnement Blazor< /h2>

Faisons un tour de l'application. En commençant par le client, le point d'entrée principal est Program.cs, qui crée le WebAssemblyHost, ajoute le composant racine App.razor, puis crée et exécute l'application.

Techniquement, le point d'entrée est wwwroot/index.html, qui charge le fichier JavaScript de Blazor’, affiche une page de chargement pendant l'initialisation de Blazor et affiche une erreur message si ce n'est pas le cas.

Publicité

App.razor gère le routage des pages à l'aide d'un composant de routeur. Cela prend en charge l'assemblage et charge toutes les pages marquées avec l'attribut @page name . Vous pouvez en savoir plus sur le routage dans les pages Razor ici.

Le routeur charge le MainLayout.razor composant, qui étend LayoutComponentBase. Cela charge le composant NavMenu.razor à côté du corps et affiche votre application.

Génial! Quant au serveur, il s'agit d'une application ASP.NET standard. Il crée un host builder et ajoute des services configurés dans Startup.cs. Notamment, il le configure pour le débogage WASM, sert les fichiers Blazor Framework et configure ses propres pages et contrôleurs Razor pour servir le contenu JSON.

S'il ne s'agissait que d'une application Blazor Server, elle n'aurait pas besoin de cette API distincte et pourrait simplement récupérer les données d'un service interne. Mais comme ce n'est pas le cas, il doit exposer ce service via le réseau, sous la forme d'un ApiController ASP.NET qui spécifie les méthodes de gestion pour différentes actions HTTP.

Les modèles pour cela sont partagés entre le client et le serveur, dans le projet partagé.

Correction des choix de couleurs horribles de Microsoft

Avant de commencer à coder, nous devons corriger quelque chose. Pour une raison quelconque, le choix de couleur par défaut de Microsoft pour les directives HTML C# dans les pages Razor utilise peut-être la pire combinaison de couleurs imaginable pour un texte violet clair sur un fond beige clair.

Heureusement, vous pouvez le modifier depuis Outils > Options :

Publicité

Sous Environnement > Polices et couleurs, sélectionnez “Directive Razor” et changez la couleur d'arrière-plan en quelque chose de plus raisonnable. Vous voulez probablement toujours qu'il se démarque, alors j'ai juste choisi le noir pur, qui sera perceptible mais non intrusif.

Vous devrez également modifier le “Script HTML côté serveur,” (qui est techniquement maintenant un nom obsolète compte tenu de l'existence de Blazor WebAssembly).

Et avec cette solution simple, vous pouvez épargner à vos yeux des heures de douleur.

Servir du contenu dynamique

Le dernier fichier que vous voudrez extraire se trouve sur le client, FetchData.razor. C'est là que le client consomme réellement l'API côté serveur, avec la page basée sur les données suivante :

Il s'agit d'une page Razor assez complexe, c'est donc un bon exemple à analyser ici.

Pour commencer, il spécifie une dérogation manuelle pour la route de la page avec @page “/fetchdata”. Il importe ensuite les modèles partagés du projet partagé et utilise également l'injection de dépendances pour lui donner un HttpClient, qui a été configuré dans Program.cs.

Publicité

Nous allons passer à le bas pour expliquer ce premier—le bloc @code contient le code C# réel pour cette page. Il contient une variable privée appelée prévisions. Ceci est initialement nul, mais lorsque la page est initialisée, elle fait une requête Web pour récupérer les données de l'API et les désérialiser.

Lorsque cette variable est mise à jour, Blazor détecte le changement et rend la page à nouveau. La page elle-même est tout ce qui se trouve entre les deux, qui commence par un en-tête et une description, mais contient ensuite une instruction @if. Il s'agit de HTML conditionnel C#, et dans ce cas, il est utilisé pour afficher le texte de chargement pendant que Blazor fait la demande à l'API. Ensuite, une fois qu'il est terminé et qu'il s'affiche à nouveau, les prévisions ne seront pas nulles et le tableau qui fera l'élément @foreach de la liste affichera une ligne du tableau.

En utilisant cela, vous pouvez rendre le contenu dynamique de vos modèles. Pour prendre en charge des opérations CRUD plus avancées et des interfaces utilisateur plus dynamiques, vous devrez utiliser des boutons et des entrées. Vous pouvez utiliser le <bouton> tags avec un attribut @onclick, qui prend une référence de méthode.

Vous pouvez utiliser EventCallbacks pour transmettre l'événement aux composants parents. Vous pouvez également utiliser des expressions Lambda pour gérer les événements en ligne, si la méthode est courte :

<button @onclick=”@(e =>heading = “New header!!!”)”> Mettre à jour l'en-tête </button>

Il existe plusieurs arguments d'événement supplémentaires que vous pouvez transmettre à ces fonctions de gestion, notamment l'emplacement de la souris, les événements de clavier et les événements tactiles.

Si vous souhaitez implémenter un champ de recherche, Blazor a des liaisons pour cela. Cependant, si vous souhaitez qu'il recherche automatiquement lorsque vous appuyez sur Entrée, et non à chaque pression de touche, vous devrez lier l'événement @onkeydown à une fonction, qui prend un objet KeyboardEventArgs, et vérifier manuellement si Entrée a été enfoncée.

Publicité

Cependant, vous ne pouvez pas obtenir la valeur d'entrée à partir de KeyboardEventArgs, cela se traduit donc par cette zone de saisie désordonnée où vous devez lier onkeydown et oninput, définir une valeur de chaîne, puis utiliser cette chaîne dans onkeydown.

< 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 } } }

Comment fonctionne le style ?

Extrêmement simple. Il existe un fichier maître site.css, mais pour le style au niveau des composants, créez simplement un fichier .razor.css pour chaque page Razor :

index.razor index.razor.css

Blazor créera automatiquement un fichier fichier CSS limité qui applique les paramètres de chaque page Razor à cette seule page Razor :

<link href=”BlazorWebAssemblyTest.Client.styles.css” rel=”stylesheet” /> /* /Pages/Counter.razor.rz.scp.css */h1[b-3xxtam6d07] { color: brown; }

Faire fonctionner des préprocesseurs comme SASS est un peu plus compliqué, mais tout à fait faisable.

Cycle de vie des composants Blazor

Comme React, Blazor a également des liaisons de cycle de vie des composants. Selon ce diagramme de l'Université Blazor, une ressource fantastique pour apprendre Blazor, le runtime Blazor les appelle dans l'ordre suivant :

SetParametersAsync et OnParametersSet sont appelés chaque fois que le parent du composant est rendu. OnInitializedAsync est également appelé ici si c'est la première fois. Ensuite, pour chaque interaction utilisateur, l'événement peut appeler StateHasChanged, qui vérifie s'il doit être rendu et déclenche à nouveau ce processus de mise à jour.

Publicité

Il y a trop de détails à énumérer ici, vous devriez donc lire le guide de l'Université Blazor, qui les explique tous, ainsi que les interactions étranges avec les méthodes async/wait. Pour restituer autant de contenu aussi rapidement que possible, Blazor peut exécuter StateHasChanged et restituer deux fois, une fois juste lorsque l'objet Task Waiter est renvoyé et une fois lorsqu'il est terminé.

Comment Blazor fonctionne-t-il avec JavaScript ?

Que vous utilisiez Blazor Server ou Blazor Desktop, vous disposez d'une interopérabilité JavaScript complète, telle que l'appel de fonctions JS à partir de code managé :

private async Task ConvertArray() { text = new(await JS.InvokeAsync<string>(“convertArray”, quoteArray)); }

Et en appelant .NET depuis JS :

DotNet.invokeMethodAsync('{ASSEMBLY NAME}', '{.NET METHOD ID}', {ARGUMENTS});

Vous pouvez en fait utiliser tous les packages NPM avec Blazor, bien que vous devriez préférer un package NuGet la plupart du temps si c'est une option.

Naviguer autour de l'utilisateur

L'un des problèmes les plus importants avec les applications Web, en particulier les applications Web à page unique (SPWA), est le routage. Chaque page Razor a un itinéraire par défaut en fonction de son nom, mais vous pouvez le remplacer et vous pouvez également ajouter plusieurs itinéraires de page à chaque page Razor. Le routeur fera correspondre chacun séparément et servira toujours le même fichier.

Cependant, si vous souhaitez diffuser un contenu différent en fonction de l'URL sur laquelle vous vous trouvez, les choses se compliquent un peu. La solution la plus simple consisterait simplement à définir une route @page pour chaque chaîne que vous souhaitez ajouter. Cela fonctionne la première fois, mais en raison de la façon dont Blazor gère les mises à jour, il n'actualisera pas la page lors de la navigation vers une nouvelle URL, car les paramètres n'ont pas changé. Vous pouvez toujours l'utiliser pour définir plusieurs orthographes de la même page, tant que ces pages ne sont pas liées les unes aux autres.

La solution au problème SPWA consiste à utiliser des routes basées sur des paramètres chaque fois que vous voulez attraper plusieurs options et établir un lien entre elles. Les paramètres peuvent être définis entre parenthèses :

Publicité

Cette configuration particulière est pour la page racine. Si vous craignez que cela corresponde à d'autres pages comme /error car il est configuré pour correspondre à tout ce qui se trouve après la racine, ne vous inquiétez pas, Blazor correspondra à d'autres pages strictement définies. avant de revenir à l'utilisation de routes basées sur des paramètres. Cependant, vous ne pouvez pas avoir plusieurs routes de paramètres sur la même route racine sans obtenir une erreur de route ambiguë.

< /p>

Dans mon cas, je voulais diriger l'utilisateur vers une nouvelle page avec un argument. Vous pouvez le faire en accédant à NavigationManager et en appelant NavigateTo :

NavManager.NavigateTo(“/search/” + searchValue);

Si vous souhaitez un routage plus avancé, vous devrez examiner les paramètres de requête.

Mise à jour manuelle de la page lors du changement d'URL

L'une des bizarreries de Blazor est qu'il ne déclenche pas de mise à jour lorsque votre URL change, même si vous avez un code avec état qui en dépend, vous devrez donc mettre à jour manuellement. Heureusement, le NavigationManager a un délégué pour le moment où l'emplacement change, et vous pouvez lier une fonction à cela.

NavigationManager.LocationChanged += HandleLocationChanged;

Vous voudrez utiliser InvokeAsync avec une fonction qui met à jour tout objet d'état dont dépend votre application. Ensuite, vous devrez appeler StateHasChanged pour déclencher une actualisation.

Vous pouvez également appeler OnParametersSetAsync à partir d'ici, si votre code dépend également d'autres paramètres d'URL et que vous ne souhaitez pas copier/coller.

Blazor Bibliothèques

L'un des avantages de Blazor est qu'il ne s'agit pas d'une toute nouvelle chose, qu'il repose sur l'épine dorsale de 20 ans d'ASP.NET et qu'il est donc déjà livré avec un écosystème diversifié de bibliothèques. Nous n'entrerons pas dans une liste d'entre eux ici, car il existe déjà la liste des super-blazeurs sur GitHub qui couvre tout.

Publicité

Cependant, une chose que vous devriez absolument be using est une bibliothèque de composants prédéfinie. Il y en a quelques-uns gratuits, mais RadZen est l'un des plus populaires, et il est complètement open source. Blazorise en est un autre excellent, même s'il n'est gratuit que pour les produits non commerciaux.

Dans les deux cas, l'utilisation de dispositions de composants prédéfinies et leur stylisation à la main plus tard permettront un prototypage rapide et accéléreront considérablement votre temps de développement. Nous les recommandons vivement.

The Future Of Blazor

Blazor est un framework vraiment unique parmi un océan de clones React basés sur JavaScript, et avec Microsoft derrière lui, il a un bel avenir. Nous avons mentionné plus tôt que Microsoft avait des plans pour Blazor Desktop, qui arrivera fin 2021.

Blazor Desktop fonctionnera un peu comme Electron, où il lance votre application dans un conteneur Chromium avec quelques liaisons pour les fonctionnalités du bureau . Sauf qu'au lieu d'utiliser Chromium, Blazor Desktop va utiliser des WebViews natifs et exécuter le code .NET directement sur la machine.

En attendant, vous pouvez réellement obtenir Blazor sur le bureau maintenant avec Electron .NET, et cela fonctionne étonnamment bien. Tout ce que vous avez à faire est de l'installer et d'ajouter Electron en tant que service ASP.NET. Vous pouvez également appeler des fonctions natives Electron à partir de C#.


Posted

in

by

Tags: