Dotnet Architecture Blazor For Web Forms Developers
Dotnet Architecture Blazor For Web Forms Developers
Consultez le journal des modifications pour voir les mises à jour du livre et les
contributions de la communauté.
PUBLIÉ PAR
Tous droits réservés. Aucune partie du contenu de ce document ne peut être reproduite
ou transmise sous quelque forme ou par quelque moyen que ce soit sans l’autorisation
écrite de l’éditeur.
Ce document est fourni « en l’état » et exprime les points de vue et les opinions de son
auteur. Les points de vue, les opinions et les informations exprimés dans cet ouvrage,
notamment l’URL et autres références à des sites web Internet, peuvent faire l’objet de
modifications sans préavis.
Certains exemples sont fournis à titre indicatif uniquement et sont fictifs. Toute
association ou lien est purement involontaire ou fortuit.
Microsoft et les marques commerciales mentionnées dans la page web « Marques » sur
https://www.microsoft.com sont des marques du groupe Microsoft.
Toutes les autres marques et tous les autres logos sont la propriété de leurs
propriétaires respectifs.
Auteurs :
Introduction
.NET a longtemps pris en charge le développement d’applications web via ASP.NET, un
ensemble complet d’infrastructures et d’outils pour la génération de tout type
d’application web. ASP.NET possède sa propre lignée d’infrastructures et technologies
web, qui trouve ses racines dans la technologie Active Server Pages (ASP) classique. Des
infrastructures comme ASP.NET Web Forms, ASP.NET MVC, Pages Web ASP.NET et, plus
récemment, ASP.NET Core, offrent un moyen productif et puissant de produire des
applications web rendues par le serveur, où le contenu de l’interface utilisateur est
généré de façon dynamique sur le serveur en réponse à des requêtes HTTP. Chaque
infrastructure ASP.NET s’adresse à un public et découle d’une philosophie de création
d’application spécifiques. ASP.NET Web Forms fourni avec la version d’origine de .NET
Framework, a ouvert la voie au développement web à l’aide de nombreux modèles
familiers pour les développeurs d’applications de bureau, comme des contrôles
d’interface utilisateur réutilisables avec une gestion simple des événements. Toutefois,
aucune offre d’ASP.NET ne permet d’exécuter du code dans le navigateur de l’utilisateur.
Cela requiert d’écrire du JavaScript et d’utiliser l’un des nombreux outils et
infrastructures qui ont gagné, puis perdu en popularité au fil des ans, tels que jQuery,
Knockout, Angular, React, etc.
Blazor est une nouvelle infrastructure web qui change les possibilités de création
d’applications web avec .NET. Blazor est une infrastructure d’interface utilisateur web
côté client basée sur C# au lieu de JavaScript. Blazor vous permet d’écrire vos
composants logiques et votre interface utilisateur côté client en C#, de les compiler
dans des assemblys .NET standard, puis de les exécuter directement dans un navigateur
utilisant d’une nouvelle norme web ouverte appelée WebAssembly. Ou bien, Blazor peut
exécuter vos composants d’interface utilisateur .NET sur le serveur, et gérer toutes les
interactions avec l’interface utilisateur de manière fluide sur une connexion en temps
réel avec le navigateur. Associé à .NET s’exécutant sur le serveur, Blazor permet un
développement web de pile complète avec .NET. Bien que Blazor partage de nombreux
points communs avec ASP.NET Web Forms, comme d’avoir un modèle de composant
réutilisable et une manière simple de gérer les événements utilisateur, il s’appuie
également sur les fondements de .NET pour fournir une expérience de développement
web moderne et hautement performante.
Ce livre présente Blazor aux développeurs ASP.NET Web Forms d’une manière familière
et pratique. Il introduit les concepts de Blazor en parallèle avec des concepts analogues
dans ASP.NET Web Forms, tout en expliquant de nouveaux concepts susceptibles d’être
moins familiers. Il couvre un vaste éventail de sujets et préoccupations, dont la création,
le routage, la disposition, la configuration et la sécurité des composants. Et bien que le
contenu de ce livre soit principalement destiné à ouvrir la voie à de nouveaux
développements, il fournit également des instructions et stratégies pour la migration
vers Blazor d’applications ASP.NET Web Forms existantes que vous souhaitez
moderniser.
Utilisation du livre
La première partie de ce livre décrit Blazor et le compare au développement
d’application web avec ASP.NET Web Forms. Le livre couvre ensuite divers aspects de
Blazor, chapitre par chapitre, en associant chaque concept de Blazor à un concept
correspondant dans ASP.NET Web Forms, ou en expliquant de façon approfondie les
concepts entièrement nouveaux. Le livre fait également régulièrement référence à un
échantillon d’application complète implémentée tant dans ASP.NET Web Forms que
dans Blazor, afin de montrer les fonctionnalités de Blazor et de fournir une étude de cas
pour la migration d’ASP.NET Web Forms vers Blazor. Vous trouverez les deux
implémentations de l’échantillon d’application (versions ASP.NET Web Forms et Blazor)
sur GitHub .
Ressources supplémentaires
Vous trouverez la page d’accueil et la documentation officielles de Blazor à l’adresse
https://blazor.net .
Next
Présentation de Blazor pour les
développeurs ASP.NET Web Forms
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
Année après année, Microsoft a introduit de nouveaux frameworks web basés sur
ASP.NET pour répondre aux tendances du développement web. Parmi ces frameworks
web, citons ASP.NET MVC, ASP.NET Web Pages et plus récemment ASP.NET Core.
Chaque fois qu’un nouveau framework sortait, certains prédisaient le déclin imminent
d’ASP.NET Web Forms et le critiquaient en affirmant que c’était un framework web
obsolète et démodé. Malgré ces prédictions, de nombreux développeurs web .NET
continuent de voir ASP.NET Web Forms comme un moyen simple, stable et productif de
faire leur travail.
À l’heure où nous rédigeons cet article, près d’un demi-million de développeurs web
utilisent ASP.NET Web Forms chaque mois. Le framework ASP.NET Web Forms est stable
au point que la documentation, les exemples, les livres et les billets de blog écrits il y a
dix ans ont gardé toute leur utilité et leur pertinence. Pour de nombreux développeurs
web .NET, « ASP.NET » reste synonyme de « ASP.NET Web Forms » comme c’était le cas
quand .NET a été conçu pour la première fois. Les arguments sur les pour et les contre
d’ASP.NET Web Forms par rapport aux autres nouveaux frameworks web .NET peuvent
continuer à faire rage. ASP.NET Web Forms reste un framework populaire pour créer des
applications web.
Malgré tout, les innovations dans le développement logiciel ne ralentissent pas. Tous les
développeurs de logiciels doivent rester au courant des nouvelles technologies et
tendances. Deux tendances en particulier méritent notre attention :
La plupart des frameworks web modernes sont aussi maintenant open source, ce qui
présente un certain nombre d’avantages. Les utilisateurs ne sont pas tenus à un seul
propriétaire de projet pour corriger les bogues et ajouter des fonctionnalités. Les projets
open source offrent une meilleure transparence sur la progression du développement et
les changements à venir. Les projets open source bénéficient des contributions de toute
une communauté et favorisent un écosystème open source de grand soutien. Malgré les
risques liés à l’open source, de nombreux consommateurs et contributeurs ont trouvé
des atténuations appropriées qui leur permettent de profiter des avantages d’un
écosystème open source de manière sûre et raisonnable. Parmi ces atténuations, citons
les contrats de licence de contributeur, les licences conviviales, les analyses de pedigree
et les fondations de soutien.
Est-ce qu’ASP.NET Web Forms tire parti du passage à l’open source et à la prise en
charge du multiplateforme ? Malheureusement, la réponse est non, ou du moins pas
autant que le reste de la plateforme. L’équipe .NET a clairement indiqué qu’ASP.NET
Web Forms ne sera pas porté sur .NET Core ou .NET 7. Pourquoi ?
Des efforts ont été faits au début de .NET Core pour porter ASP.NET Web Forms. Le
nombre de changements cassants requis a été jugé trop élevé. Il a également été admis
que, même pour Microsoft, le nombre de frameworks web qu’il peut prendre en charge
simultanément est limité. Peut-être qu’une personne de la communauté embrassera la
cause et créera une version open source et multiplateforme d’ASP.NET Web Forms. Le
code source d’ASP.NET Web Forms a été mis à la disposition de tout le monde sous
forme de référence. Mais pour l’instant, il semble qu’ASP.NET Web Forms reste réservé à
Windows et sans modèle de contribution open source. Si la prise en charge du
multiplateforme ou l’open source deviennent importants pour vos scénarios, vous
devrez alors rechercher quelque chose de nouveau.
Cela signifie-t-il qu’ASP.NET Web Forms est mort et ne devrait plus être utilisé ? Bien sûr
que non ! Tant que le .NET Framework est fourni avec Windows, ASP.NET Web Forms
reste un framework pris en charge. Pour de nombreux développeurs Web Forms,
l’absence de prise en charge du multiplateforme et de l’open source n’est pas un
problème. Si vous n’avez pas besoin de la prise en charge du multiplateforme, de l’open
source ou de l’une des autres nouvelles fonctionnalités de .NET Core ou de .NET 7, vous
pouvez très bien continuer à utiliser ASP.NET Web Forms sur Windows. ASP.NET Web
Forms reste et restera un moyen productif d’écrire des applications web pendant encore
de nombreuses années.
Toutefois, les navigateurs sont devenus des plateformes polyvalentes. Ils implémentent
un nombre toujours croissant de normes web ouvertes qui accordent l’accès aux
fonctionnalités de l’ordinateur de l’utilisateur. Pourquoi ne pas tirer parti de la puissance
de calcul, du stockage, de la mémoire et autres ressources de l’appareil client ? Les
interactions avec l’interface utilisateur en particulier peuvent bénéficier d’une expérience
plus riche et plus interactive lorsqu’elles sont gérées au moins partiellement ou
complètement côté client. La logique et les données qui doivent être gérées sur le
serveur peuvent toujours être gérées côté serveur. Les appels d’API web ou même les
protocoles en temps réel, tels que WebSockets, peuvent être utilisés. Les développeurs
web peuvent disposer gratuitement de ces avantages s’ils sont prêts à écrire en
JavaScript. Les frameworks d’interface utilisateur côté client, comme Angular, React et
Vue, simplifient le développement web côté client et ont gagné en popularité. Les
développeurs ASP.NET Web Forms peuvent également tirer parti du client et même
bénéficier d’un support immédiat avec des frameworks JavaScript intégrés comme
ASP.NET AJAX.
Des travaux sur l’exécution de .NET sur WebAssembly ont été annoncés fin 2017 et
publiés en 2020, avec prise en charge dans .NET 5 et ultérieur. La capacité à exécuter du
code .NET directement dans le navigateur permet le développement web full-stack avec
.NET.
Blazor offre une excellente prise en charge des outils dans Visual Studio et Visual Studio
Code. Le framework comprend également un modèle de composant IU complet et
dispose de fonctionnalités intégrées pour :
Formulaires et validation
Injection de dépendances
Routage côté client
Dispositions
Débogage dans le navigateur
Interopérabilité JavaScript
Blazora beaucoup en commun avec ASP.NET Web Forms. Les deux frameworks offrent
des modèles de programmation IU avec état qui sont basés sur des composants et
pilotés par des événements. La principale différence architecturale est qu’ASP.NET Web
Forms s’exécute uniquement sur le serveur. Blazor peut s’exécuter sur le client dans le
navigateur. Mais si vous venez d’ASP.NET Web Forms, beaucoup d’aspects vous
sembleront familiers dans Blazor. Blazor est une solution naturelle pour les
développeurs ASP.NET Web Forms qui cherchent un moyen de tirer parti du
développement côté client et du futur multiplateforme open source de .NET.
Ce livre fournit une présentation de Blazor qui s’adresse spécialement aux développeurs
ASP.NET Web Forms. Chaque concept Blazor est présenté dans le contexte de
fonctionnalités et pratiques ASP.NET Web Forms analogues. À la fin de ce livre, vous
aurez compris :
Précédent Suivant
Comparaison des architectures ASP.NET
Web Forms et Blazor
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
Même si ASP.NET Web Forms et Blazor comptent de nombreux concepts similaires, leur
fonctionnement présente des différences. Ce chapitre examine les rouages internes et
les architectures d’ASP.NET Web Forms et de Blazor.
Balisage HTML
Code C# ou Visual Basic
Classe code-behind contenant des fonctionnalités de logique et de gestion des
événements
Commandes
Les contrôles sont des unités réutilisables de l’interface utilisateur web qui peuvent être
placées et manipulées programmatiquement sur une page. Les pages sont composées
de fichiers qui se terminent par .aspx et qui contiennent des balises, des contrôles et du
code. Les classes code-behind sont dans des fichiers avec le même nom de base et une
extension .aspx.cs ou .aspx.vb, selon le langage de programmation utilisé. Il est
intéressant de noter que le serveur web interprète le contenu des fichiers .aspx et les
compile chaque fois qu’ils changent. Cette recompilation se produit même si le serveur
web est déjà en cours d’exécution.
Les contrôles peuvent être générés avec le balisage et livrés comme contrôles
utilisateur. Un contrôle utilisateur dérive de la classe UserControl et a une structure
similaire à la page. Le balisage des contrôles utilisateur est stocké dans un fichier .ascx.
Une classe code-behind associée réside dans un fichier .ascx.cs ou .ascx.vb. Les contrôles
peuvent aussi être générés intégralement avec le code en héritant de la classe de base
WebControl ou CompositeControl .
Les pages ont également un cycle de vie d’événement complet. Chaque page déclenche
des événements pour l’initialisation, le chargement, le prérendu et le déchargement des
événements qui se produisent lorsque le runtime ASP.NET exécute le code de la page
pour chaque requête.
Les contrôles d’une page sont généralement republiés sur la même page qui présentait
le contrôle et ont avec eux le contenu d’un champ de formulaire masqué appelé
ViewState . Le champ ViewState contient des informations sur l’état des contrôles au
moment où ils ont été rendus et présentés sur la page, ce qui permet au runtime
ASP.NET de comparer et d’identifier les changements du contenu soumis au serveur.
Blazor
Blazor est un framework d’interface utilisateur web côté client similaire à celui des
frameworks front-end JavaScript comme Angular ou React. Blazor gère les interactions
utilisateur et restitue les mises à jour nécessaires de l’interface utilisateur. Blazorn’est pas
basé sur un modèle requête-réponse. Les interactions utilisateur sont gérées comme
des événements qui ne sont pas dans le contexte d’une requête HTTP en particulier.
Les applications Blazor sont constituées d’un ou plusieurs composants racines qui sont
restitués sur une page HTML.
La façon dont l’utilisateur spécifie où les composants doivent s’afficher et la façon dont
les composants sont ensuite reliés pour les interactions utilisateur sont spécifiques au
modèle d’hébergement.
Les composantsBlazor sont des classes .NET qui représentent un élément réutilisable de
l’interface utilisateur. Chaque composant conserve son propre état et spécifie sa propre
logique de rendu, qui peut englober le rendu d’autres composants. Les composants
indiquent des gestionnaires d’événements pour des interactions utilisateur spécifiques
afin de mettre à jour l’état du composant.
Une fois qu’un composant gère un événement, Blazor affiche le composant et suit ce qui
a changé dans la sortie rendue. Les composants ne s’affichent pas directement dans le
modèle DOM (Document Object Model). Ils s’affichent sur une représentation en
mémoire du modèle DOM appelé RenderTree pour permettre à Blazor de suivre les
modifications. Blazor compare la sortie qui vient d’être rendue à la sortie précédente
pour générer un diff de l’interface utilisateur qu’il applique ensuite efficacement au
modèle DOM.
Les composants peuvent également indiquer manuellement qu’ils doivent être rendus si
leur état change en dehors d’un événement d’interface utilisateur normal. Blazor utilise
un SynchronizationContext pour appliquer un seul thread logique d’exécution. Les
méthodes de cycle de vie d’un composant et les rappels d’événements qui sont
déclenchés par Blazor sont exécutés sur ce SynchronizationContext .
Précédent Suivant
Modèles d’hébergement d’applications
Blazor
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
Les applications Blazor peuvent être hébergées de l’une des façons suivantes :
Les assemblys téléchargés sont des assemblys .NET normaux, comme vous les utiliseriez
dans n’importe quelle autre application .NET. Étant donné que le runtime prend en
charge .NET Standard, vous pouvez utiliser des bibliothèques .NET Standard existantes
avec votre application BlazorWebAssembly. Toutefois, ces assemblys s’exécutent
toujours dans le bac à sable de sécurité du navigateur. Certaines fonctionnalités peuvent
lever un PlatformNotSupportedException, comme une tentative d’accéder au système
de fichiers ou d’ouvrir des connexions réseau arbitraires.
Lorsque l’application se charge, le runtime .NET est démarré et pointé vers l’assembly de
l’application. La logique de démarrage de l’application s’exécute et les composants
racines sont rendus. Blazor calcule les mises à jour de l’interface utilisateur en fonction
de la sortie rendue des composants. Les mises à jour du DOM sont ensuite appliquées.
Blazor Les applications WebAssembly s’exécutent purement côté client. Ces applications
peuvent être déployées sur des solutions d’hébergement de sites statiques, comme
GitHub Pages ou Azure Static Website Hosting. .NET n’est pas nécessaire sur le serveur.
Un lien profond vers des parties de l’application nécessite généralement une solution de
routage sur le serveur. La solution de routage redirige les demandes à la racine de
l’application. Par exemple, cette redirection peut être gérée à l’aide de règles de
réécriture d’URL dans IIS.
Pour obtenir tous les avantages de Blazor et du développement web .NET de pile
complète, hébergez votre application BlazorWebAssembly avec ASP.NET Core. En
utilisant .NET sur le client et le serveur, vous pouvez facilement partager du code et
créer votre application à l’aide d’un ensemble cohérent de langages, de frameworks et
d’outils. Blazor fournit des modèles pratiques pour configurer une solution qui contient
à la fois une application BlazorWebAssembly et un projet hôte ASP.NET Core. Lorsque la
solution est générée, les fichiers statiques générés à partir de l’application Blazor sont
hébergés par l’application ASP.NET Core avec le routage de secours déjà configuré.
Applications serveur Blazor
Rappelez-vous de la discussion d’architecture Blazor ; les composants Blazor rendent
leur sortie à une abstraction intermédiaire appelée RenderTree . L’infrastructure Blazor
compare ensuite ce qui a été rendu avec ce qui a été rendu précédemment. Les
différences sont appliquées au DOM. Les composants Blazor sont découplés de la façon
dont leur sortie rendue est appliquée. Par conséquent, les composants eux-mêmes n’ont
pas à s’exécuter dans le même processus que le processus mettant à jour l’interface
utilisateur. En fait, ils n’ont même pas à s’exécuter sur la même machine.
Dans les applications serveur Blazor, les composants s’exécutent sur le serveur au lieu du
côté client dans le navigateur. Les événements d’interface utilisateur qui se produisent
dans le navigateur sont envoyés au serveur via une connexion en temps réel. Les
événements sont distribués aux bonnes instances de composant. Le rendu des
composants, et la différence calculée de l’interface utilisateur, est sérialisé et envoyé au
navigateur où il est appliqué au DOM.
Le modèle d’hébergement serveur Blazor peut sembler familier si vous avez utilisé
ASP.NET AJAX et le contrôle UpdatePanel. Le contrôle UpdatePanel gère l’application de
mises à jour partielles de page en réponse au déclenchement d’événements sur la page.
Lors du déclenchement, le UpdatePanel demande une mise à jour partielle, puis
l’applique sans avoir à actualiser la page. L’état de l’interface utilisateur est géré à l’aide
de ViewState . Les applications serveur Blazor sont légèrement différentes en cela que
l’application nécessite une connexion active avec le client. En outre, l’état de l’interface
utilisateur est conservé sur le serveur. En dehors de ces différences, les deux modèles
sont conceptuellement similaires.
La taille du téléchargement est beaucoup plus petite qu’une application côté client
et l’application se charge beaucoup plus rapidement.
L’application tire pleinement parti des fonctionnalités de serveur, notamment
l’utilisation de toutes les API compatibles .NET.
.NET sur le serveur est utilisé pour exécuter l’application. Ainsi, les outils .NET
existants, comme le débogage, fonctionnent comme prévu.
Les clients légers sont pris en charge. Par exemple, les applications côté serveur
fonctionnent avec les navigateurs qui ne prennent pas en charge WebAssembly et
sur les appareils limités en ressources.
La base de code .NET/C# de l’application, y compris le code du composant de
l’application, n’est pas servie aux clients.
Les inconvénients du modèle d’hébergement serveur Blazor sont les suivants :
Être hébergées sur IIS, en tant que fichiers statiques ou en tant qu’application
ASP.NET Core.
Tirer parti de la flexibilité d’ASP.NET Core pour être hébergées sur différentes
plateformes et infrastructures de serveur. Par exemple, vous pouvez héberger une
application Blazor à l’aide de Nginx ou Apache sur Linux. Pour plus d’informations
sur la publication et le déploiement d’applications Blazor, consultez la
Blazordocumentation Hébergement et déploiement.
Dans la section suivante, nous allons examiner la façon dont les projets pour
BlazorWebAssembly et les applications serveur Blazor sont configurés.
Précédent Suivant
Structure de projet pour les applications
Blazor
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
Pour créer votre première application Blazor, suivez les instructions des étapes de
démarrage de Blazor. Vous pouvez suivre les instructions pour créer une application
Blazor Server ou une application BlazorWebAssembly hébergée dans ASP.NET Core. À
l’exception de la logique spécifique au modèle d’hébergement, la plupart du code dans
les deux projets est identique.
Fichier projet
Les applications Blazor Server sont des projets .NET. Le fichier projet de l’application
Blazor Server est d’une simplicité à toute épreuve :
XML
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
</Project>
XML
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly"
Version="7.0.0" />
<PackageReference
Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer"
Version="7.0.0" PrivateAssets="all" />
</ItemGroup>
</Project>
En comparaison, un projet ASP.NET Web Forms par défaut compte près de 300 lignes de
code XML dans son fichier .csproj, dont la plupart liste explicitement les différents
fichiers de code et de contenu dans le projet. Depuis la publication de .NET 5, les
applications Blazor Server et BlazorWebAssembly peuvent facilement partager un
runtime unifié.
Bien qu’elles soient prises en charge, les références d’assembly individuelles sont moins
courantes dans les projets .NET. La plupart des dépendances de projet sont gérées
comme des références de package NuGet. Vous devez uniquement référencer les
dépendances de package de niveau supérieur dans les projets .NET. Les dépendances
transitives sont incluses automatiquement. Au lieu d’utiliser le fichier packages.config
que l’on trouve couramment dans les projets ASP.NET Web Forms pour référencer les
packages, les références de package sont ajoutées au fichier projet à l’aide de l’élément
<PackageReference> .
XML
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup>
Point d’entrée
Le point d’entrée de l’application Blazor Server est défini dans le fichier Program.cs,
comme vous le verriez dans une application console. Lorsque l’application s’exécute, elle
crée et exécute une instance hôte web en utilisant les valeurs par défaut propres aux
applications web. L’hôte web gère le cycle de vie de l’application Blazor Server et
configure les services au niveau de l’hôte. Parmi ces services, citons par exemple la
configuration, la journalisation, l’injection de dépendances et le serveur HTTP. Ce code
est en grande partie réutilisable et reste souvent inchangé.
C#
using BlazorApp3.Areas.Identity;
using BlazorApp3.Data;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
Les applications Blazor n’utilisent pas de fichier Global.asax pour définir la logique de
démarrage de l’application. À la place, cette logique est contenue dans Program.cs ou
dans une classe Startup associée qui est référencée dans Program.cs. Dans les deux cas,
ce code est utilisé pour configurer l’application et tous les services spécifiques à
l’application.
Dans une application Blazor Server, le fichier Program.cs montré est utilisé pour
configurer le point de terminaison pour la connexion en temps réel utilisée par Blazor
entre les navigateurs clients et le serveur.
C#
using BlazorApp1;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
await builder.Build().RunAsync();
Fichiers statiques
Contrairement aux projets ASP.NET Web Forms, les fichiers d’un projet Blazor ne
peuvent pas tous être demandés en tant que fichiers statiques. Seuls les fichiers du
dossier wwwroot sont adressables sur le web. Ce dossier est appelé « racine web » de
l’application. Tout ce qui se trouve en dehors de la racine web de l’application n’est pas
adressable sur le web. Cette configuration fournit un niveau de sécurité supplémentaire
qui empêche l’exposition accidentelle des fichiers projet sur le web.
Configuration
La configuration dans les applications ASP.NET Web Forms est généralement gérée à
l’aide d’un ou plusieurs fichiers web.config. Les applications Blazor n’ont généralement
pas de fichiers web.config. Si c’est le cas, le fichier est utilisé uniquement pour configurer
les paramètres spécifiques à IIS lorsqu’ils sont hébergés sur IIS. De leur côté, les
applications Blazor Server utilisent les abstractions de configuration ASP.NET Core.
(Actuellement, les applications BlazorWebAssembly ne prennent pas en charge les
mêmes abstractions de configuration, mais ce sera peut-être une fonctionnalité qui sera
ajoutée plus tard.) Par exemple, l’application Blazor Server par défaut stocke certains
paramètres dans appsettings.json.
JSON
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Vous en apprendrez plus sur la configuration dans les projets ASP.NET Core dans la
section Configuration.
Composants Razor
La plupart des fichiers des projets Blazor sont des fichiers .razor. Razor est un langage
de création de modèles basé sur HTML et C# qui est utilisé pour générer
dynamiquement l’interface utilisateur web. Les fichiers .razor définissent les composants
qui constituent l’interface utilisateur de l’application. Les composants sont en grande
partie identiques pour les applications Blazor Server et BlazorWebAssembly. Les
composants dans Blazor sont analogues aux contrôles utilisateur dans ASP.NET Web
Forms.
Chaque fichier de composant Razor est compilé dans une classe .NET lors de la
génération du projet. La classe générée capture l’état, la logique de rendu, les méthodes
de cycle de vie, les gestionnaires d’événements et autres logiques du composant. Vous
en apprendrez plus sur la création de composants dans la section Création de
composants d’interface utilisateur réutilisables avec Blazor.
Les fichiers _Imports.razor ne sont pas des fichiers de composants Razor. En fait, ils
définissent un ensemble de directives Razor à importer dans les autres fichiers .razor
dans le même dossier et dans ses sous-dossiers. Par exemple, un fichier _Imports.razor
est un moyen conventionnel d’ajouter des directives using pour les espaces de noms
couramment utilisés :
razor
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using BlazorApp1
@using BlazorApp1.Shared
Pages
Où sont les pages dans les applications Blazor ? Blazor ne définit pas d’extension de
fichier distincte pour les pages adressables, comme les fichiers .aspx dans les
applications ASP.NET Web Forms. En fait, les pages sont définies en affectant des routes
aux composants. Une route est généralement attribuée en utilisant la directive Razor
@page . Par exemple, le composant Counter créé dans le fichier Pages/Counter.razor
définit la route suivante :
razor
@page "/counter"
Le routage dans Blazor est géré côté client, et non sur le serveur. Lorsque l’utilisateur
circule dans le navigateur, Blazor intercepte la navigation, puis rend le composant avec
la route correspondante.
Vous en apprendrez plus sur le routage dans Blazor dans la section Pages, routage et
mises en page.
Layout
Dans les applications ASP.NET Web Forms, une mise en page commune est gérée à
l’aide de pages maîtres (Site.Master). Dans les applications Blazor, la mise en page est
gérée avec des composants de mise en page (Shared/MainLayout.razor). Les
composants de mise en page sont abordés plus en détail dans la section Page, routage
et mises en page.
Amorcer Blazor
Pour amorcer Blazor, l’application doit :
Spécifier où, dans la page, le composant racine (App.Razor) doit être rendu.
Ajouter le script du framework Blazor correspondant.
Dans l’application Blazor Server, la page hôte du composant racine est définie dans le
fichier _Host.cshtml. Ce fichier définit une page Razor, pas un composant. Les pages
Razor utilisent la syntaxe Razor pour définir une page adressable au serveur, très
similaire à une page .aspx.
razor
@page "/"
@namespace BlazorApp3.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = "_Layout";
}
L’attribut render-mode est utilisé pour définir où un composant de niveau racine doit
être rendu. L’option RenderMode indique la manière dont le composant doit être rendu.
Le tableau suivant présente les options RenderMode prises en charge.
Option Description
razor
@using Microsoft.AspNetCore.Components.Web
@namespace BlazorApp3.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
<link href="BlazorApp3.styles.css" rel="stylesheet" />
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
@RenderBody()
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond
until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for
details.
</environment>
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.server.js"></script>
</body>
</html>
Dans l’application BlazorWebAssembly, la page hôte est un fichier HTML statique simple
sous wwwroot/index.html. L’élément <div> avec l’ID appelé app est utilisé pour indiquer
où le composant racine doit être rendu.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no" />
<title>BlazorApp1</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
<link href="BlazorApp1.styles.css" rel="stylesheet" />
</head>
<body>
<div id="app">Loading...</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
</body>
</html>
Le composant racine à rendre est spécifié dans le fichier Program.cs de l’application avec
la flexibilité nécessaire pour inscrire les services via l’injection de dépendances. Pour plus
d’informations, consultez Injection de dépendances Blazor ASP.NET Core.
C#
Sortie de la génération
Lorsqu’un projet Blazor est généré, tous les fichiers de composant et de code Razor sont
compilés dans un seul assembly. Contrairement aux projets ASP.NET Web Forms, Blazor
ne prend pas en charge la compilation du runtime de la logique d’interface utilisateur.
Précédent Suivant
Démarrage des applications
Article • 10/05/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor for ASP NET Web Forms
Developers for Azure (Blazor pour les développeurs ASP NET Web Forms pour
Azure), disponible sur la documentation .NET ou en tant que PDF téléchargeable
gratuitement qui peut être lu hors connexion.
Télécharger le PDF
Les applications écrites pour ASP.NET ont généralement un fichier global.asax.cs qui
définit l’événement Application_Start qui contrôle les services configurés et mis à
disposition pour le rendu HTML et le traitement .NET. Ce chapitre explique les légères
différences entre ASP.NET Core et Blazor Server.
Avec ASP.NET Core et Blazor, ces méthodes sont simplifiées et consolidées dans la
classe Startup ou sont éliminées au profit des technologies web courantes.
C#
using BlazorApp1.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
Une fois le app généré par le builder , le reste des appels sur app configurent son
pipeline HTTP. Avec ces appels, nous déclarons de haut en bas le Middleware qui gérera
chaque requête envoyée à notre application. La plupart de ces fonctionnalités de la
configuration par défaut ont été réparties dans les fichiers de configuration de web
forms et se trouvent désormais à un seul endroit pour pouvoir s’y référer facilement.
La ligne suivante est la première qui réplique l’une des options de configuration à partir
des web forms : UseRouting . Cette méthode ajoute le routeur ASP.NET Core au pipeline
et peut être configuré ici ou dans les fichiers individuels vers lesquels il peut envisager
d’effectuer le routage. Vous trouverez plus d’informations sur la configuration du
routage dans la section Routage.
Les appels app.Map* finaux de cette section définissent les points de terminaison
qu’écoute ASP.NET Core. Ces itinéraires correspondent aux emplacements accessibles
sur le web auxquels vous pouvez accéder sur le serveur web et sur lesquels vous pouvez
recevoir du contenu géré par .NET que vous avez retourné. La première entrée
MapBlazorHub configure un hub SignalR à utiliser pour fournir la connexion en temps
réel et persistante au serveur où sont gérés l’état et le rendu des composants Blazor.
L’appel de méthode MapFallbackToPage indique l’emplacement accessible sur le web de
la page qui démarre l’application Blazor et configure également l’application pour gérer
les requêtes de liaison approfondie côté client. Vous verrez cette fonctionnalité si vous
ouvrez un navigateur et accédez directement à l’itinéraire géré par Blazor dans votre
application, comme /counter dans le modèle de projet par défaut. La requête est gérée
par la page de secours _Host.cshtml, qui exécute ensuite le routeur Blazor et affiche la
page du compteur.
La dernière ligne démarre l’application, ce qui n’était pas nécessaire dans les web forms
(car IIS était utilisé pour l’exécution).
XML
Pour plus d’informations sur les deux stratégies de gestion de vos fichiers CSS et
JavaScript, consultez la documentation Regrouper et minimiser les ressources statiques
dans ASP.NET Core.
Précédent Suivant
Créer des composants d’interface
utilisateur réutilisables avec Blazor
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
L’un des avantages de ASP.NET Web Forms est qu’il permet d’encapsuler des éléments
de code d’interface utilisateur (IU) réutilisables dans des contrôles IU réutilisables. Des
contrôles utilisateur personnalisés peuvent être définis par balisage à l’aide de fichiers
.ascx. Vous pouvez également créer des contrôles serveur élaborés dans le code avec
prise en charge complète du concepteur.
Présentation de Razor
Razor est un langage de balisage léger basé sur HTML et C#. Avec Razor, vous pouvez
effectuer une transition transparente entre le balisage et le code C# pour définir votre
logique de rendu de composant. Lorsque le fichier .razor est compilé, la logique de
rendu est capturée de manière structurée dans une classe .NET. Le nom de la classe
compilée est extrait du nom de fichier .razor. L’espace de noms est extrait de l’espace de
noms par défaut pour le projet et du chemin du dossier, ou vous pouvez spécifier
explicitement l’espace de noms à l’aide de la directive @namespace (plus d’informations
sur les directives Razor ci-dessous).
La logique de rendu d’un composant est créée à l’aide du balisage HTML normal avec
une logique dynamique ajoutée à l’aide de C#. Le caractère @ est utilisé pour passer à
C#. Razor est généralement intelligent pour savoir quand vous êtes revenu au HTML. Par
exemple, le composant suivant affiche une balise <p> avec l’heure actuelle :
razor
<p>@DateTime.Now</p>
Pour spécifier explicitement le début et la fin d’une expression C#, utilisez des
parenthèses :
razor
<p>@(DateTime.Now)</p>
Razor facilite également l’utilisation du flux de contrôle C# dans votre logique de rendu.
Par exemple, vous pouvez afficher du code HTML de manière conditionnelle comme suit
:
razor
@if (value % 2 == 0)
{
<p>The value was even.</p>
}
Vous pouvez également générer une liste d’éléments à l’aide d’une boucle C# foreach
normale comme suit :
razor
<ul>
@foreach (var item in items)
{
<li>@item.Text</li>
}
</ul>
Les directives Razor, comme les directives dans ASP.NET Web Forms, contrôlent de
nombreux aspects de la compilation d’un composant Razor. Les exemples incluent les
éléments suivants du composant :
Espace de noms
Classe de base
Interfaces implémentées
Paramètres génériques
Espaces de noms importés
Itinéraires
razor
@namespace MyComponentNamespace
Le tableau suivant récapitule les différentes directives Razor utilisées dans Blazor et leurs
équivalents ASP.NET Web Forms, s’ils existent.
Les composants Razor utilisent également largement les attributs de directive sur les
éléments pour contrôler différents aspects de la façon dont les composants sont
compilés (gestion des événements, liaison de données, références d’éléments & de
composant, etc.). Les attributs de directive suivent tous une syntaxe générique
commune où les valeurs entre parenthèses sont facultatives :
razor
@directive(-suffix(:name))(="value")
Le tableau suivant récapitule les différents attributs des directives Razor utilisés dans
Blazor.
Les différents attributs de directive utilisés par Blazor ( @onclick , @bind , @ref et ainsi de
suite) sont couverts dans les sections ci-dessous et les chapitres ultérieurs.
La plupart des syntaxes utilisées dans les fichiers .aspx et .ascx ont des syntaxes
parallèles dans Razor. Vous trouverez ci-dessous une comparaison simple des syntaxes
pour ASP.NET Web Forms et Razor.
Pour ajouter des membres à la classe de composant Razor, utilisez la directive @code .
Cette technique est similaire à l’utilisation d’un bloc <script runat="server">...
</script> dans un contrôle utilisateur ou une page ASP.NET Web Forms.
razor
@code {
int count = 0;
void IncrementCount()
{
count++;
}
}
Étant donné que Razor est basé sur C#, il doit être compilé à partir d’un projet C#
(.csproj). Vous ne pouvez pas compiler les fichiers .razor à partir d’un projet Visual Basic
(.vbproj). Vous pouvez toujours référencer des projets Visual Basic à partir de votre
projet Blazor. L’inverse est également vrai.
razor
<Counter />
Pensez aux composants Razor comme vous le feriez pour les types .NET, car c’est
exactement ce qu’ils sont. Si l’assembly contenant le composant est référencé, le
composant est disponible pour utilisation. Pour placer l’espace de noms du composant
dans l’étendue, appliquez la directive @using :
razor
@using MyComponentLib
<Counter />
Comme indiqué dans les projets Blazor par défaut, il est courant de placer des directives
@using dans un fichier _Imports.razor afin de les importer dans tous les fichiers .razor
Si l’espace de noms d’un composant n’est pas dans l’étendue, vous pouvez spécifier un
composant à l’aide de son nom de type complet, comme vous pouvez le faire en C# :
razor
<MyComponentLib.Counter />
razor
@page "/"
<PageTitle>Home</PageTitle>
Le contenu de cet élément peut être dynamique, par exemple en montrant le nombre
actuel de messages :
razor
<PageTitle>@MessageCount messages</PageTitle>
Notez que si plusieurs composants d’une page particulière incluent des balises
<PageTitle> , seul le dernier sera affiché (car chacun remplacera le précédent).
Paramètres de composant
Dans ASP.NET Web Forms, vous pouvez envoyer des paramètres et des données vers
des contrôles à l’aide de propriétés publiques. Ces propriétés peuvent être définies dans
le balisage à l’aide d’attributs ou définies directement dans le code. Les composants
Razor fonctionnent de manière similaire, bien que les propriétés des composants
doivent également être marquées avec l’attribut [Parameter] pour être considérés
comme des paramètres de composant.
razor
<h1>Counter</h1>
@code {
int currentCount = 0;
[Parameter]
public int IncrementAmount { get; set; } = 1;
void IncrementCount()
{
currentCount+=IncrementAmount;
}
}
Pour spécifier un paramètre de composant dans Blazor, utilisez un attribut comme vous
le feriez dans ASP.NET Web Forms :
razor
C#
[Parameter]
[SupplyParameterFromQuery(Name = "IncBy")]
public int IncrementAmount { get; set; } = 1;
Par exemple, pour vous protéger contre les exceptions possibles levées à partir du
composant Counter , déclarez-le dans un <ErrorBoundary> et spécifiez éventuellement
un message à afficher s’il existe une exception :
razor
<ErrorBoundary>
<ChildContent>
<Counter />
</ChildContent>
<ErrorContent>
Oops! The counter isn't working right now; please try again later.
</ErrorContent>
</ErrorBoundary>
Si vous n’avez pas besoin de spécifier de contenu d’erreur personnalisé, vous pouvez
simplement encapsuler le composant directement :
razor
<ErrorBoundary>
<Counter />
</ErrorBoundary>
Un message par défaut indiquant « Une erreur s’est produite » s’affiche si une exception
non gérée se produit dans le composant encapsulé.
Gestionnaires d’événements
ASP.NET Web Forms et Blazor fournissent tous deux un modèle de programmation basé
sur les événements pour gérer les événements d’interface utilisateur. Les exemples de
ces événements incluent les clics de bouton et l’entrée de texte. Dans ASP.NET Web
Forms, vous utilisez des contrôles de serveur HTML pour gérer les événements
d’interface utilisateur exposés par le DOM, ou vous pouvez gérer les événements
exposés par les contrôles de serveur web. Les événements sont exposés sur le serveur
via des demandes de publication de formulaire. Prenons l’exemple de clic sur le bouton
Web Forms suivant :
Counter.ascx
ASP.NET (C#)
Counter.ascx.cs
C#
Dans Blazor, vous pouvez inscrire des gestionnaires pour les événements d’interface
utilisateur DOM directement à l’aide d’attributs de directive de la forme @on{event} .
L’espace réservé {event} représente le nom de l’événement. Par exemple, vous pouvez
écouter les clics de bouton comme suit :
razor
@code {
void OnClick()
{
Console.WriteLine("The button was clicked!");
}
}
razor
@code {
void OnClick(MouseEventArgs e)
{
Console.WriteLine($"Mouse clicked at {e.ScreenX}, {e.ScreenY}.");
}
}
razor
razor
@code {
async Task OnClick()
{
var result = await Http.GetAsync("api/values");
}
}
Une fois qu’un événement est géré, le composant est rendu pour tenir compte des
modifications d’état du composant. Avec les gestionnaires d’événements asynchrones, le
composant est rendu immédiatement une fois l’exécution du gestionnaire terminée. Le
composant est rendu à nouveau une fois l’opération asynchrone Task terminée. Ce
mode d’exécution asynchrone permet d’afficher une interface utilisateur appropriée
alors que le Task asynchrone est toujours en cours.
razor
@if (showMessage)
{
@if (message == null)
{
<p><em>Loading...</em></p>
}
else
{
<p>The message is: @message</p>
}
}
@code
{
bool showMessage = false;
string message;
razor
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClick { get; set; }
}
Liaison de données
Blazor fournit un mécanisme simple pour lier des données d’un composant d’interface
utilisateur à l’état du composant. Cette approche diffère des fonctionnalités d’ASP.NET
Web Forms pour lier des données de sources de données aux contrôles d’interface
utilisateur. Nous aborderons la gestion des données provenant de différentes sources
de données dans la section Gestion des données.
Pour créer une liaison de données bidirectionnelle d’un composant d’interface utilisateur
à l’état du composant, utilisez l’attribut de directive @bind . Dans l’exemple suivant, la
valeur de la case à cocher est liée au champ isChecked .
razor
@code {
bool isChecked;
}
Lorsque le composant est rendu, la valeur de la case à cocher est définie sur la valeur du
champ isChecked . Lorsque l’utilisateur bascule la case à cocher, l’événement onchange
est déclenché et le champ isChecked est défini sur la nouvelle valeur. La syntaxe @bind
dans ce cas équivaut au balisage suivant :
razor
razor
@code {
string text;
}
Les composants peuvent également prendre en charge la liaison de données sur leurs
paramètres. Pour lier des données, définissez un paramètre de rappel d’événement
portant le même nom que le paramètre pouvant être lié. Le suffixe « Changed » est
ajouté au nom.
PasswordBox.razor
razor
Password: <input
value="@Password"
@oninput="OnPasswordChanged"
type="@(showPassword ? "text" : "password")" />
@code {
private bool showPassword;
[Parameter]
public string Password { get; set; }
[Parameter]
public EventCallback<string> PasswordChanged { get; set; }
razor
@code {
string password;
}
Modifications d'état
Si l’état du composant a changé en dehors d’un événement d’interface utilisateur
normal ou d’un rappel d’événement, le composant doit signaler manuellement qu’il doit
être rendu à nouveau. Pour signaler que l’état d’un composant a changé, appelez la
méthode StateHasChanged sur le composant.
C#
razor
@code {
protected override void OnInitialized()
{
AppState.OnChange += StateHasChanged
}
}
Counter.ascx.cs
C#
Les composants Razor possèdent aussi un cycle de vie bien défini. Le cycle de vie d’un
composant peut être utilisé pour initialiser l’état du composant et implémenter des
comportements de composant avancés.
Toutes les méthodes de cycle de vie des composants de Blazor ont des versions
synchrones et asynchrones. Le rendu des composants est synchrone. Vous ne pouvez
pas exécuter de logique asynchrone dans le cadre du rendu du composant. Toute
logique asynchrone doit s’exécuter dans le cadre d’une méthode de cycle de vie async .
OnInitialized
Les méthodes OnInitialized et OnInitializedAsync sont utilisées pour initialiser le
composant. Un composant est généralement initialisé après son rendu. Une fois qu’un
composant est initialisé, il peut être rendu plusieurs fois avant qu’il ne soit finalement
supprimé. La méthode OnInitialized est similaire à l’événement Page_Load dans les
pages et contrôles ASP.NET Web Forms.
C#
OnParametersSet
Les méthodes OnParametersSet et OnParametersSetAsync sont appelées lorsqu’un
composant a reçu des paramètres de son parent et que la valeur est affectée aux
propriétés. Ces méthodes sont exécutées après l’initialisation des composants et chaque
fois que le composant est rendu.
C#
OnAfterRender
Les méthodes OnAfterRender et OnAfterRenderAsync sont appelées une fois que le rendu
d’un composant est terminé. Les références d’élément et de composant sont remplies à
ce stade (plus d’informations sur ces concepts ci-dessous). L’interactivité avec le
navigateur est activée à ce stade. Les interactions avec le DOM et l’exécution JavaScript
peuvent se produire en toute sécurité.
C#
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
...
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await ...
}
}
Le paramètre firstRender est true la première fois que le composant est rendu ; sinon,
sa valeur est false .
IDisposable
Les composants Razor peuvent implémenter IDisposable pour supprimer des
ressources lorsque le composant est supprimé de l’interface utilisateur. Un composant
Razor peut implémenter IDispose à l’aide de la directive @implements :
razor
@using System
@implements IDisposable
...
@code {
public void Dispose()
{
...
}
}
Pour capturer une référence de composant dans Blazor, utilisez l’attribut de directive
@ref . La valeur de l’attribut doit correspondre au nom d’un champ réglable avec le
même type que le composant référencé.
razor
@code {
MyLoginDialog loginDialog = default!;
void OnSomething()
{
loginDialog.Show();
}
}
Lors du rendu du composant parent, le champ est rempli avec l’instance du composant
enfant. Vous pouvez ensuite appeler des méthodes sur l’instance du composant ou la
manipuler autrement.
Les composants Razor peuvent également être utilisés comme modèles en définissant
des paramètres de composant de type RenderFragment ou RenderFragment<T> . Un
RenderFragment représente un bloc de balisage Razor qui peut ensuite être rendu par le
composant. Un RenderFragment<T> est un bloc de balisage Razor qui prend un
paramètre qui peut être spécifié lorsque le fragment de rendu est rendu.
Contenu enfant
Les composants Razor peuvent capturer leur contenu enfant en tant que
RenderFragment et afficher ce contenu dans le cadre du rendu du composant. Pour
capturer le contenu enfant, définissez un paramètre de composant de type
RenderFragment et nommez-le ChildContent .
ChildContentComponent.razor
razor
<div>@ChildContent</div>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
razor
<ChildContentComponent>
<ChildContent>
<p>The time is @DateTime.Now</p>
</ChildContent>
</ChildContentComponent>
Paramètres de modèle
Un composant Razor basé sur un modèle peut également définir plusieurs paramètres
de composant de type RenderFragment ou RenderFragment<T> . Le paramètre d’un
RenderFragment<T> peut être spécifié lorsqu’il est appelé. Pour spécifier un paramètre de
SimpleListView.razor
razor
@typeparam TItem
@Heading
<ul>
@foreach (var item in Items)
{
<li>@ItemTemplate(item)</li>
}
</ul>
@code {
[Parameter]
public RenderFragment Heading { get; set; }
[Parameter]
public RenderFragment<TItem> ItemTemplate { get; set; }
[Parameter]
public IEnumerable<TItem> Items { get; set; }
}
Lorsque vous utilisez un composant modèle, les paramètres de modèle peuvent être
spécifiés à l’aide d’éléments enfants qui correspondent aux noms des paramètres. Les
arguments de composant de type RenderFragment<T> transmis en tant qu’éléments ont
un paramètre implicite nommé context . Vous pouvez modifier le nom de ce paramètre
d’implémentation à l’aide de l’attribut Context sur l’élément enfant. Tous les paramètres
de type générique peuvent être spécifiés à l’aide d’un attribut qui correspond au nom
du paramètre de type. Le paramètre de type est déduit si possible :
razor
HTML
<h1>My list</h1>
<ul>
<li><p>The message is: message1</p></li>
<li><p>The message is: message2</p></li>
<ul>
Code-behind
Un composant Razor est généralement créé dans un fichier .razor unique. Toutefois, il
est également possible de séparer le code et le balisage à l’aide d’un fichier code-
behind. Pour utiliser un fichier de composant, ajoutez un fichier C# qui correspond au
nom de fichier du composant, mais avec une extension .cs ajoutée (Counter.razor.cs).
Utilisez le fichier C# pour définir une classe de base pour le composant. Vous pouvez
nommer la classe de base comme vous le souhaitez, mais il est courant de nommer la
classe de façon semblable à la classe de composant, avec une extension Base ajoutée
( CounterBase ). La classe basée sur le composant doit également dériver de
ComponentBase . Ensuite, dans le fichier de composant Razor, ajoutez la directive
@inherits pour spécifier la classe de base du composant ( @inherits CounterBase ).
Counter.razor
razor
@inherits CounterBase
<h1>Counter</h1>
Counter.razor.cs
C#
La visibilité des membres du composant dans la classe de base doit être protected ou
public pour être visible par la classe de composant.
Ressources supplémentaires
Ce qui précède n’est pas un traitement exhaustif de tous les aspects des composants
Razor. Pour plus d’informations sur la façon de Créer et utiliser des composants Razor
ASP.NET Core, consultez la documentation Blazor.
Précédent Suivant
Pages, routage et dispositions
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
Les applications ASP.NET Web Forms sont composées de pages définies dans les fichiers
.aspx. L’adresse de chaque page est basée sur son chemin d’accès de fichier physique
dans le projet. Lorsqu’un navigateur envoie une requête à la page, le contenu de la page
est rendu dynamiquement sur le serveur. Le rendu tient compte à la fois du balisage
HTML de la page et des contrôles du serveur.
Dans Blazor, chaque page de l’application est un composant, généralement défini dans
un fichier .razor, avec un ou plusieurs itinéraires spécifiés. Le routage se produit
principalement côté client sans impliquer une demande de serveur spécifique. Le
navigateur effectue d’abord une requête à l’adresse racine de l’application. Un
composant Router racine dans l’application Blazor gère ensuite l’interception des
demandes de navigation et les transfère au composant approprié.
Blazor prend également en charge le lien profond. Le lien profond se produit lorsque le
navigateur envoie une requête à un itinéraire spécifique autre que la racine de
l’application. Les demandes de liens profonds envoyés au serveur sont acheminées vers
l’application Blazor, qui achemine ensuite la requête côté client vers le composant
approprié.
Une page simple dans ASP.NET Web Forms peut contenir le balisage suivant :
Name.aspx
ASP.NET (C#)
Name.aspx.cs
C#
Name.razor
razor
@page "/Name"
@layout MainLayout
<div>
What is your name?<br />
<input @bind="text" />
<button @onclick="OnClick">Submit</button>
</div>
<div>
@if (name != null)
{
@:Hello @name
}
</div>
@code {
string text;
string name;
void OnClick() {
name = text;
}
}
razor
@page "/counter"
La syntaxe du modèle de routage est la même syntaxe de base que celle utilisée pour le
routage dans ASP.NET Web Forms. Les paramètres de routage sont spécifiés dans le
modèle à l’aide d’accolades. Blazor lie les valeurs de routage aux paramètres de
composant portant le même nom (sans respect de la casse).
razor
@page "/product/{id}"
<h1>Product @Id</h1>
@code {
[Parameter]
public string Id { get; set; }
}
Vous pouvez également spécifier des contraintes sur la valeur du paramètre de routage.
Par exemple, pour limiter l’ID produit à un int :
razor
@page "/product/{id:int}"
<h1>Product @Id</h1>
@code {
[Parameter]
public int Id { get; set; }
}
Pour obtenir la liste complète des contraintes d’itinéraire prises en charge par Blazor,
consultez Contraintes de routage.
Composant routeur
Le routage dans Blazor est géré par le composant Router . Le composant Router est
généralement utilisé dans le composant racine de l’application (App.razor).
razor
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData"
DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
C#
Le retour d’une réponse de redirection n’est généralement pas possible dans Blazor.
Blazor n’utilise pas de modèle de demande-réponse. Toutefois, vous pouvez déclencher
des navigations de navigateur directement, comme vous le pouvez avec JavaScript.
razor
@page "/"
@inject NavigationManager NavigationManager
<button @onclick="Navigate">Navigate</button>
@code {
void Navigate() {
NavigationManager.NavigateTo("counter");
}
}
Pour obtenir une description de tous les membres NavigationManager , consultez URI et
assistance à l’état de navigation.
URL de base
Si votre application Blazor est déployée sous un chemin d’accès de base, vous devez
spécifier l’URL de base dans les métadonnées de la page à l’aide de la balise <base>
pour le routage vers la propriété de travail. Si la page hôte de l’application est rendue
par le serveur à l’aide de Razor, vous pouvez utiliser la syntaxe ~/ pour spécifier
l’adresse de base de l’application. Si la page hôte est HTML statique, vous devez
spécifier explicitement l’URL de base.
HTML
Mise en page
La mise en page dans ASP.NET Web Forms est gérée par les pages maîtres. Les pages
maîtres définissent un modèle avec un ou plusieurs espaces réservés de contenu qui
peuvent ensuite être fournis par des pages individuelles. Les pages maîtres sont définies
dans les fichiers .master et commencent par la directive <%@ Master %> . Le contenu des
fichiers .master est codé comme vous le feriez pour une page .aspx , mais avec l’ajout de
contrôles <asp:ContentPlaceHolder> pour marquer où les pages peuvent fournir du
contenu.
Site.master
ASP.NET (C#)
<!DOCTYPE html>
<html lang="en">
<head runat="server">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%: Page.Title %> - My ASP.NET Application</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
</head>
<body>
<form runat="server">
<div class="container body-content">
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
<hr />
<footer>
<p>© <%: DateTime.Now.Year %> - My ASP.NET
Application</p>
</footer>
</div>
</form>
</body>
</html>
Dans Blazor, vous gérez la mise en page à l’aide de composants de mise en page. Les
composants de disposition héritent de LayoutComponentBase , qui définit une propriété
unique Body de type RenderFragment , qui peut être utilisée pour restituer le contenu de
la page.
MainLayout.razor
razor
@inherits LayoutComponentBase
<h1>Main layout</h1>
<div>
@Body
</div>
Lorsque la page avec une mise en page est affichée, la page est rendue dans le contenu
de la disposition spécifiée à l’emplacement où la disposition affiche sa propriété Body .
Pour appliquer une mise en page à une page, utilisez la directive @layout :
razor
@layout MainLayout
Vous pouvez spécifier la disposition de tous les composants d’un dossier et de sous-
dossiers à l’aide d’un fichier _Imports.razor. Vous pouvez également spécifier un layout
par défaut pour toutes vos pages à l’aide du Composant routeur.
Les pages maîtres peuvent définir plusieurs espaces réservés de contenu, mais les
layouts dans Blazor n’ont qu’une seule propriété Body . Cette limitation des composants
de layout Blazor sera traitée dans une prochaine version.
Les pages maîtres dans ASP.NET Web Forms peuvent être imbriquées. Autrement dit,
une page maître peut également utiliser une page maître. Les composants de layout
dans Blazor peuvent également être imbriqués. Vous pouvez appliquer un composant
de layout à un composant de layout. Le contenu du layout interne sera affiché dans le
layout externe.
ChildLayout.razor
razor
@layout MainLayout
<h2>Child layout</h2>
<div>
@Body
</div>
Index.razor
razor
@page "/"
@layout ChildLayout
<p>I'm in a nested layout!</p>
HTML
<h1>Main layout</h1>
<div>
<h2>Child layout</h2>
<div>
<p>I'm in a nested layout!</p>
</div>
</div>
Les mises en page dans Blazor ne définissent généralement pas les éléments HTML
racines d’une page ( <html> , <body> , <head> , etc.). Les éléments HTML racine sont plutôt
définis dans la page hôte d’une application Blazor, qui est utilisée pour afficher le
contenu HTML initial de l’application (voir Bootstrap Blazor). La page hôte peut afficher
plusieurs composants racines pour l’application avec le balisage environnant.
Les composants dans Blazor, y compris les pages, ne peuvent pas afficher de balises
<script> . Cette restriction de rendu existe, car les balises <script> sont chargées une
seule fois, puis ne peuvent pas être modifiées. Un comportement inattendu peut se
produire si vous essayez de restituer dynamiquement les balises à l’aide de la syntaxe
Razor. Au lieu de cela, toutes les balises <script> doivent être ajoutées à la page hôte
de l’application.
Précédent Suivant
Gestion de l'état
Article • 09/05/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor for ASP NET Web Forms
Developers for Azure (Blazor pour les développeurs ASP NET Web Forms pour
Azure), disponible sur la documentation .NET ou en tant que PDF téléchargeable
gratuitement qui peut être lu hors connexion.
Télécharger le PDF
La gestion de l’état est un concept clé d’applications Web Forms, facilitée par les
fonctionnalités ViewState, État de session, État de l’application et Postback. Ces
fonctionnalités avec état de l’infrastructure ont permis de masquer la gestion de l’état
requise pour une application et de permettre aux développeurs d’applications de se
concentrer sur les fonctionnalités à fournir. Avec ASP.NET Core et Blazor, certaines de
ces fonctionnalités ont été déplacées et certaines ont été complètement supprimées. Ce
chapitre explique comment maintenir l’état et fournir les mêmes fonctionnalités avec les
nouvelles fonctionnalités de Blazor.
Avec Blazor Server, l’application conserve une connexion continue avec le serveur. L’état
de l’application, appelé circuit, est conservé dans la mémoire du serveur pendant que la
connexion est considérée comme active. L’état est supprimé uniquement lorsque
l’utilisateur quitte l’application ou une page particulière de l’application. Tous les
membres des composants actifs sont disponibles entre les interactions avec le serveur.
L’état du composant est facilement disponible et n’est pas reconstruit entre les
interactions.
L’état n’est pas transmis au navigateur.
Pour les raisons précédentes, ne vous fiez pas uniquement à l’état du composant à
résider en mémoire sur le serveur. Votre application doit également inclure un magasin
de données de stockage pour les données entre les requêtes. Voici quelques exemples
simples de cette stratégie :
Pour plus d’informations sur la gestion de l’état dans les applications Blazor, consultez
Gestion d’état ASP.NET Core Blazor.
La signature de l’objet .NET Framework Session n’est pas identique à l’objet ASP.NET
Core Session . Envisagez la documentation relative à la nouvelle session ASP.NET Core
avant de décider de migrer et d’utiliser la nouvelle fonctionnalité d’état de session.
La session est disponible dans ASP.NET Core et Blazor Server, mais il est déconseillé de
l’utiliser en faveur du stockage des données dans un référentiel de données de manière
appropriée. L’état de session n’est pas non plus fonctionnel si les visiteurs refusent
l’utilisation des cookies HTTP dans votre application en raison de problèmes de
confidentialité.
La configuration d’ASP.NET Core et l’état de session est disponible dans l’article Session
et gestion de l’état dans ASP.NET Core.
État de l’application
L’objet Application dans l’infrastructure Web Forms fournit un référentiel de requêtes
croisées massif pour interagir avec la configuration et l’état de toute l’application. L’état
de l’application était un emplacement idéal pour stocker différentes propriétés de
configuration d’application qui seraient référencées par toutes les requêtes, quel que
soit l’utilisateur qui effectue la requête. Le problème avec l’objet Application était que
les données n’étaient pas conservées sur plusieurs serveurs. L’état de l’objet
d’application a été perdu entre les redémarrages.
Comme avec Session , il est recommandé que les données se déplacent vers un magasin
de stockage persistant accessible par plusieurs instances de serveur. S’il existe des
données volatiles auxquelles vous souhaitez accéder entre les requêtes et les
utilisateurs, vous pouvez facilement les stocker dans un service singleton qui peut être
injecté dans des composants qui nécessitent ces informations ou interactions.
C#
C#
app.AddSingleton<MyApplicationState>();
razor
L’objet MyApplicationState est créé une seule fois sur le serveur, et la valeur
VisitorCounter est extraite et sortie dans l’étiquette du composant. La valeur
VisitorCounter doit être conservée et récupérée à partir d’un magasin de données de
Dans le navigateur
Les données d’application peuvent également être stockées côté client sur l’appareil de
l’utilisateur afin qu’elles soient disponibles ultérieurement. Il existe deux fonctionnalités
de navigateur qui permettent la persistance des données dans différentes étendues du
navigateur de l’utilisateur :
rechargée, le navigateur est fermé et rouvert, ou un autre onglet est ouvert avec la
même URL, puis le même localStorage est fourni par le navigateur
sessionStorage – étendu à l’onglet actuel du navigateur de l’utilisateur. Si l’onglet
est rechargé, l’état persiste. Toutefois, si l’utilisateur ouvre un autre onglet à votre
application ou ferme et ouvre à nouveau le navigateur, l’état est perdu.
Vous pouvez écrire du code JavaScript personnalisé pour interagir avec ces
fonctionnalités, ou il existe un certain nombre de packages NuGet que vous pouvez
utiliser pour fournir cette fonctionnalité. Un de ces packages est
Microsoft.AspNetCore.ProtectedBrowserStorage .
Pour obtenir des instructions sur l’utilisation de ce package pour interagir avec
localStorage et sessionStorage , consultez l’article Blazor State Management (Gestion
d’état Blazor).
Précédent Suivant
Formulaires et validation
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
Blazor fournit un ensemble de composants d’entrée. Les composants d’entrée gèrent les
données de champ de liaison à un modèle et valident l’entrée utilisateur lorsque le
formulaire est envoyé.
InputSelect <select>
InputText <input>
InputTextArea <textarea>
C#
using System;
using System.ComponentModel.DataAnnotations;
[Required]
public string Classification { get; set; }
[Range(1, 100000,
ErrorMessage = "Accommodation invalid (1-100000).")]
public int MaximumAccommodation { get; set; }
[Required]
[Range(typeof(bool), "true", "true",
ErrorMessage = "This form disallows unapproved ships.")]
public bool IsValidatedDesign { get; set; }
[Required]
public DateTime ProductionDate { get; set; }
}
Le composant suivant illustre la création d’un formulaire dans Blazor, basé sur le type de
modèle Starship :
razor
<p>
<label for="identifier">Identifier: </label>
<InputText id="identifier" @bind-Value="starship.Identifier" />
<ValidationMessage For="() => starship.Identifier" />
</p>
<p>
<label for="description">Description (optional): </label>
<InputTextArea id="description" @bind-Value="starship.Description"
/>
</p>
<p>
<label for="classification">Primary Classification: </label>
<InputSelect id="classification" @bind-
Value="starship.Classification">
<option value="">Select classification ...</option>
<option value="Exploration">Exploration</option>
<option value="Diplomacy">Diplomacy</option>
<option value="Defense">Defense</option>
</InputSelect>
<ValidationMessage For="() => starship.Classification" />
</p>
<p>
<label for="accommodation">Maximum Accommodation: </label>
<InputNumber id="accommodation" @bind-
Value="starship.MaximumAccommodation" />
<ValidationMessage For="() => starship.MaximumAccommodation" />
</p>
<p>
<label for="valid">Engineering Approval: </label>
<InputCheckbox id="valid" @bind-Value="starship.IsValidatedDesign"
/>
<ValidationMessage For="() => starship.IsValidatedDesign" />
</p>
<p>
<label for="productionDate">Production Date: </label>
<InputDate id="productionDate" @bind-Value="starship.ProductionDate"
/>
<ValidationMessage For="() => starship.ProductionDate" />
</p>
<button type="submit">Submit</button>
</EditForm>
@code {
private Starship starship = new Starship();
Après l’envoi du formulaire, les données liées au modèle n’ont pas été enregistrées dans
un magasin de données, par exemple une base de données. Dans une application Blazor
WebAssembly, les données doivent être envoyées au serveur. Par exemple, à l’aide d’une
requête HTTP POST. Dans une application serveur Blazor, les données sont déjà sur le
serveur, mais elles doivent être conservées. La gestion de l'accès aux données dans les
applications Blazor est abordée dans la section Traitement des données.
Ressources supplémentaires
Pour plus d’informations sur les formulaires et la validation dans les applications Blazor,
consultez la documentation Blazor.
Précédent Suivant
Utilisation des données
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
L’accès aux données est l’épine dorsale d’une application ASP.NET Web Forms. Si vous
créez des formulaires pour le web, qu’advient-il de ces données ? Avec Web Forms, il
existe plusieurs techniques d’accès aux données que vous pouvez utiliser pour interagir
avec une base de données :
Data Sources
ADO.NET
Entity Framework
Les sources de données étaient des contrôles que vous pouviez placer sur une page
Web Forms et configurer comme d’autres contrôles. Visual Studio fournissait un
ensemble convivial de boîtes de dialogue pour configurer et lier les contrôles à vos
pages Web Forms. Les développeurs qui apprécient une approche « low code » ou « no
code » préféraient cette technique lorsque Web Forms a été publié pour la première
fois.
ADO.NET est l’approche de bas niveau pour interagir avec une base de données. Vos
applications pouvaient créer une connexion à la base de données avec des commandes,
des tables de données et des jeux de données à des fins d’interaction. Les résultats
pouvaient ensuite être liés aux champs à l’écran avec peu de code. L’inconvénient de
cette approche était que chaque ensemble d’objets ADO.NET ( Connection , Command et
DataTable ) était lié aux bibliothèques fournies par un fournisseur de base de données.
L’utilisation de ces composants rendait le code rigide et difficile à migrer vers une autre
base de données.
Entity Framework
Entity Framework (EF) est le framework open source de mappage objet-relationnel géré
par .NET Foundation. Initialement publié avec .NET Framework, EF permet de générer du
code pour les connexions de base de données, les schémas de stockage et les
interactions. Avec cette abstraction, vous pouvez vous concentrer sur les règles métier
de votre application et autoriser la gestion de la base de données par un administrateur
de base de données approuvé. Dans .NET, vous pouvez utiliser une version mise à jour
d’EF appelée EF Core. EF Core permet de générer et de gérer les interactions entre votre
code et la base de données avec une série de commandes disponibles pour vous à l’aide
de l’outil en ligne de commande dotnet ef . Examinons quelques exemples pour vous
aider à utiliser une base de données.
EF Code First
Un moyen rapide de commencer à créer vos interactions de base de données consiste à
commencer par les objets de classe que vous souhaitez utiliser. EF fournit un outil
permettant de générer le code de base de données approprié pour vos classes. Cette
approche est appelée développement « Code First ». Considérez la classe Product
suivante pour un exemple d’application de vitrine que nous voulons stocker dans une
base de données relationnelle comme Microsoft SQL Server.
C#
[Required]
public string Name { get; set; }
[MaxLength(4000)]
public string Description { get; set; }
[Range(0, 99999,99)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
}
Le produit a une clé primaire et trois champs supplémentaires qui seraient créés dans
notre base de données :
Nous devons ajouter cette classe Product à une classe de contexte de base de données
qui définit les opérations de connexion et de traduction avec notre base de données.
C#
C#
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer("MY DATABASE CONNECTION STRING"));
Le code précédent se connecte à une base de données SQL Server avec la chaîne de
connexion spécifiée. Vous pouvez placer la chaîne de connexion dans votre fichier
appsettings.json, des variables d’environnement ou d’autres emplacements de stockage
de configuration et remplacer cette chaîne incorporée de manière appropriée.
Vous pouvez ensuite générer la table de base de données appropriée pour cette classe à
l’aide des commandes suivantes :
CLI .NET
La première commande définit les modifications que vous apportez au schéma de base
de données en tant que nouvelle migration EF appelée Create Product table . Une
migration définit comment appliquer et supprimer vos nouvelles modifications de base
de données.
Une fois eappliqué, vous disposez d’une table simple Product dans votre base de
données et de certaines nouvelles classes ajoutées au projet qui aident à gérer le
schéma de base de données. Vous pouvez trouver ces classes générées, par défaut, dans
un nouveau dossier appelé Migrations. Lorsque vous apportez des modifications à la
classe Product ou ajoutez des classes associées que vous souhaitez faire interagir avec
votre base de données, vous devez réexécuter les commandes en ligne de commande
avec un nouveau nom de migration. Cette commande génère un autre ensemble de
classes de migration pour mettre à jour votre schéma de base de données.
EF Database First
Pour les bases de données existantes, vous pouvez générer les classes pour EF Core à
l’aide des outils en ligne de commande .NET. Pour créer la structure des classes, utilisez
une variante de la commande suivante :
CLI .NET
dotnet ef dbcontext scaffold "CONNECTION STRING"
Microsoft.EntityFrameworkCore.SqlServer -c MyDbContext -t Product -t
Customer
C#
// in Program.cs
builder.Services.AddHttpClient("github", client =>
{
client.BaseAddress = new Uri("http://api.github.com/");
// Github API versioning
client.DefaultRequestHeaders.Add("Accept",
"application/vnd.github.v3+json");
// Github requires a user-agent
client.DefaultRequestHeaders.Add("User-Agent", "BlazorWebForms-Sample");
});
Chaque fois que vous devez accéder aux données à partir de GitHub, créez un client
avec le nom github . Le client est configuré avec l’adresse de base et les en-têtes de
demande sont définis de manière appropriée. Injectez les éléments IHttpClientFactory
dans vos composants Blazor avec la directive @inject ou un attribut [Inject] sur une
propriété. Créez votre client nommé et interagissez avec les services à l’aide de la
syntaxe suivante :
razor
...
@code {
protected override async Task OnInitializedAsync()
{
var client = factory.CreateClient("github");
var response = await client.GetAsync("repos/dotnet/docs/issues");
response.EnsureStatusCode();
var content = await response.Content.ReadAsStringAsync();
}
}
Précédent Suivant
Modules, gestionnaires et intergiciels
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
Une application ASP.NET Core repose sur une série d’intergiciels. L’intergiciel est
composé de gestionnaires organisés dans un pipeline pour gérer les requêtes et les
réponses. Dans une application Web Forms, les gestionnaires et modules HTTP résolvent
des problèmes similaires. Dans ASP.NET Core, les modules, les gestionnaires,
Global.asax.cs et le cycle de vie de l’application sont remplacés par des intergiciels. Dans
ce chapitre, vous allez découvrir les intergiciels dans le contexte d’une application
Blazor.
Vue d’ensemble
Le pipeline de requête ASP.NET Core est composé d’une séquence de délégués de
requête, appelés l’un après l’autre. Le diagramme suivant illustre le concept. Le thread
d’exécution suit les flèches noires.
Le diagramme précédent n’a pas de concept d’événements de cycle de vie. Ce concept
est fondamental pour la façon dont les requêtes ASP.NET Web Forms sont gérées. Ce
système facilite la raison du processus qui se produit et permet d’insérer des intergiciels
à tout moment. L’intergiciel s’exécute dans l’ordre dans lequel il est ajouté au pipeline
de requête. Il est également ajouté dans le code au lieu des fichiers de configuration,
généralement dans Startup.cs.
Katana
Les lecteurs familiarisés avec Katana se sentiront à l’aise dans ASP.NET Core. En fait,
Katana est un framework à partir duquel ASP.NET Core dérive. Il a introduit des modèles
d’intergiciels et de pipelines similaires pour ASP.NET 4.x. L’intergiciel conçu pour Katana
peut être adapté pour fonctionner avec le pipeline ASP.NET Core.
Intergiciels courants
ASP.NET 4.x inclut de nombreux modules. De la même manière, ASP.NET Core dispose
également de nombreux composants d’intergiciels. Les modules IIS peuvent être utilisés
dans certains cas avec ASP.NET Core. Dans d’autres cas, l’intergiciel ASP.NET Core natif
peut être disponible.
Cette liste n’est pas exhaustive, mais devrait vous donner une idée des correspondances
qui existent entre les deux frameworks. Pour obtenir une liste plus détaillée, consultez
Modules IIS avec ASP.NET Core.
Intergiciels personnalisés
Un intergiciel intégré peut ne pas gérer tous les scénarios nécessaires pour une
application. Dans ce cas, il est logique de créer votre propre intergiciel. Il existe plusieurs
façons de définir l’intergiciel (middleware), le plus simple étant un délégué simple.
Examinez l’intergiciel (middleware) suivant, qui accepte une demande de culture d’une
chaîne de requête :
C#
if (!string.IsNullOrWhiteSpace(cultureQuery))
{
var culture = new CultureInfo(cultureQuery);
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}
Le middleware peut également être défini en tant que classe, soit en implémentant
l’interface IMiddleware , soit en suivant la convention d’intergiciel. Pour plus
d’informations, consultez Écrire un intergiciel ASP.NET Core personnalisé.
Précédent Suivant
la configuration d’une application ;
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
C#
var configurationValue =
ConfigurationManager.AppSettings["ConfigurationSettingName"];
var connectionString =
ConfigurationManager.ConnectionStrings["MyDatabaseConnectionName"].Connectio
nString;
Avec ASP.NET Core et Blazor côté serveur, le fichier web.config peut être présent si votre
application est hébergée sur un serveur Windows IIS. Mais il n’existe aucune interaction
ConfigurationManager avec cette configuration et vous pouvez recevoir une
ASP.NET Core a été conçu pour prendre en charge le cloud et faciliter la configuration
des applications pour les opérateurs et les développeurs. ASP.NET Core prend en
compte l’environnement et identifie s’il est en cours d’exécution dans votre
environnement Production ou Development . L’indicateur d’environnement est défini
dans la variable d’environnement système ASPNETCORE_ENVIRONMENT . Si aucune valeur
n’est configurée, l’application s’exécute par défaut dans l’environnement Production .
JSON
{
"section0": {
"key0": "value",
"key1": "value"
},
"section1": {
"key0": "value",
"key1": "value"
}
}
Lorsqu’il est présenté avec le modèle JSON précédent, le système de configuration
aplatit les valeurs enfants et référence leurs chemins hiérarchiques complets. Un
caractère deux-points ( : ) sépare chaque propriété de la hiérarchie. Par exemple, la clé
configuration section1:key0 permet d’accéder à la valeur du section1 littéral de
l’objet key0 .
Secrets utilisateur
Les secrets utilisateur sont les suivants :
CLI .NET
CLI .NET
Pour plus d’informations sur la création, le stockage et la gestion des secrets utilisateur,
consultez le document Stockage sécurisé des secrets d’application en développement
dans ASP.NET Core.
Variables d'environnement
L’ensemble suivant de valeurs chargées dans la configuration de votre application
représente les variables d’environnement du système. Tous les paramètres de variable
d’environnement de votre système sont désormais accessibles via l’API de configuration.
Les valeurs hiérarchiques sont aplaties et séparées par un caractère deux-points lors de
la lecture depuis votre application. Toutefois, certains systèmes d’exploitation
n’autorisent pas les noms de variables d’environnement contenant le caractère deux-
points. ASP.NET Core résout cette limitation en convertissant les valeurs comportant des
traits de soulignement doubles ( __ ) en deux-points lorsqu’elles sont accessibles. La
valeur Parent:ApiKey de la section des secrets d'utilisateur ci-dessus peut être
remplacée par la variable d'environnement Parent__ApiKey .
CLI .NET
Retour de web.config
Si vous avez déployé votre application pour Windows sur IIS, le fichier web.config
configure toujours IIS pour gérer votre application. Par défaut, IIS ajoute une référence
au module ASP.NET Core (ANCM). ANCM est un module IIS natif qui héberge votre
application à la place du serveur web Kestrel. Cette section web.config ressemble au
balisage XML suivant :
XML
XML
<aspNetCore processPath="dotnet"
arguments=".\MyApp.dll"
stdoutLogEnabled="false"
stdoutLogFile=".\logs\stdout"
hostingModel="inprocess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development"
/>
<environmentVariable name="Parent:ApiKey" value="67890" />
</environmentVariables>
</aspNetCore>
razor
C#
Dans ASP.NET Core, vous pouvez spécifier une hiérarchie de classes qui recevra les
valeurs de configuration. Ces classes :
Pour l'exemple appsettings.json précédent, vous pourriez définir les classes suivantes
pour capturer les valeurs :
C#
C#
services.Configure<MyConfig>(Configuration);
Dans le reste de l'application, vous pouvez ajouter un paramètre d'entrée aux classes ou
une directive @inject dans les modèles Razor de type IOptions<MyConfig> pour recevoir
les paramètres de configuration fortement typés. La propriété IOptions<MyConfig>.Value
renverra la valeur MyConfig obtenue à partir des paramètres de configuration.
razor
Précédent Suivant
Sécurité : Authentification et
autorisation dans ASP.NET Web Forms
et Blazor
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
La migration d’une application Web Forms ASP.NET vers Blazor nécessite très
probablement une mise à jour de la façon dont l’authentification et l’autorisation sont
effectuées, en supposant que l’application avait configuré l’authentification. Ce chapitre
explique comment migrer à partir du modèle de fournisseur universel ASP.NET Web
Forms (pour l’appartenance, les rôles et les profils utilisateur) et comment utiliser
ASP.NET Core Identity à partir d’applications Blazor. Bien que ce chapitre traite des
étapes et des considérations générales, les étapes détaillées et les scripts sont
disponibles dans la documentation référencée.
Les fournisseurs universels fonctionnent avec un schéma de base de données SQL qui
inclut des tables telles que aspnet_Applications , aspnet_Membership , aspnet_Roles et
aspnet_Users . Lorsqu’il est configuré en exécutant la commande aspnet_regsql.exe, les
fournisseurs installent des tables et des procédures stockées qui fournissent toutes les
requêtes et commandes nécessaires pour fonctionner avec les données sous-jacentes.
Le schéma de base de données et ces procédures stockées ne sont pas compatibles
avec les systèmes ASP.NET Identity et ASP.NET Core Identity plus récents. Les données
existantes doivent donc être migrées vers le nouveau système. La figure 1 montre un
exemple de schéma de table configuré pour les fournisseurs universels.
Le fournisseur universel gère les utilisateurs, l’appartenance, les rôles et les profils. Les
utilisateurs reçoivent des identificateurs globaux uniques et des informations de base
telles que userId, userName, etc. sont stockées dans la table aspnet_Users . Les
informations d’authentification, telles que le mot de passe, le format de mot de passe, le
sel de mot de passe, les compteurs de verrouillage et les détails, etc. sont stockées dans
la table aspnet_Membership . Les rôles se composent simplement de noms et
d’identificateurs uniques, qui sont attribués aux utilisateurs via la table d’association
aspnet_UsersInRoles , fournissant une relation plusieurs-à-plusieurs.
Si votre système existant utilise des rôles en plus de l’appartenance, vous devez migrer
les comptes d’utilisateur, les mots de passe associés, les rôles et l’appartenance au rôle
dans ASP.NET Core Identity. Vous devrez également probablement mettre à jour votre
code où vous effectuez actuellement des vérifications de rôle à l’aide des instructions if
pour exploiter à la place des filtres déclaratifs, des attributs et/ou de l’assistance des
balises. Nous examinerons plus en détail les considérations relatives à la migration à la
fin de ce chapitre.
XML
<?xml version="1.0"?>
<configuration>
<system.web>
<authentication mode="Forms">
<forms defaultUrl="~/home.aspx" loginUrl="~/login.aspx"
slidingExpiration="true" timeout="2880"></forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
XML
<location path="login.aspx">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
XML
<location path="/admin">
<system.web>
<authorization>
<allow roles="Administrators" />
<deny users="*" />
</authorization>
</system.web>
</location>
La configuration ci-dessus, lorsqu’elle est combinée aux autres, limite l’accès au dossier
/admin et toutes les ressources qu’il contient aux membres du rôle « Administrateurs ».
Cette restriction peut également être appliquée en plaçant un fichier web.config distinct
dans la racine du dossier /admin .
Ce code peut être utilisé à la fois dans la logique code-behind et dans la page elle-
même :
HTML
C#
Dans le code ci-dessus, le contrôle d’accès en fonction du rôle (RBAC) est utilisé pour
déterminer si certains éléments de la page, tels qu’un SecretPanel , sont visibles en
fonction du rôle de l’utilisateur actuel.
En règle générale, les applications ASP.NET Web Forms configurent la sécurité dans le
fichier web.config , puis ajoutent des vérifications supplémentaires si nécessaire dans les
pages .aspx et leurs fichiers code-behind .aspx.cs associés. La plupart des applications
tirent parti du fournisseur d’appartenance universel, fréquemment avec le fournisseur de
rôles supplémentaires.
En plus des rôles, ASP.NET Core Identity prend en charge les concepts des
revendications et des stratégies. Bien qu’un rôle corresponde spécifiquement à un
ensemble de ressources auxquelles un utilisateur dans ce rôle doit pouvoir accéder, une
revendication fait simplement partie de l’identité d’un utilisateur. Une revendication est
une paire valeur de nom qui représente ce que l’objet est, et non ce que le sujet peut
faire.
C#
services.AddAuthorization(options =>
{
options.AddPolicy("CanadiansOnly", policy =>
policy.RequireClaim(ClaimTypes.Country, "Canada"));
});
Que vous utilisiez des stratégies ou des rôles, vous pouvez spécifier qu’une page
particulière dans votre application Blazor nécessite ce rôle ou cette stratégie avec
l’attribut [Authorize] , appliqué avec la directive @attribute .
Exiger un rôle :
C#
C#
Si vous avez besoin d’accéder à l’état d’authentification, aux rôles ou aux revendications
d’un utilisateur dans votre code, il existe deux façons principales d’obtenir cette
fonctionnalité. La première consiste à recevoir l’état d’authentification en tant que
paramètre en cascade. La seconde consiste à accéder à l’état à l’aide d’un
AuthenticationStateProvider injecté. Les détails de chacune de ces approches sont
C#
[CascadingParameter]
private Task<AuthenticationState> authenticationStateTask { get; set; }
C#
C#
@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider
Avec le fournisseur en place, vous pouvez accéder à l’utilisateur avec le code suivant :
C#
if (user.Identity.IsAuthenticated)
{
// work with user.Claims and/or user.Roles
}
Pour travailler avec les utilisateurs et les revendications (dans des applications Blazor
Server) vous devrez peut-être également injecter un UserManager<T> (utilisez
IdentityUser par défaut) que vous pouvez utiliser pour énumérer et modifier les
C#
C#
Si vous avez besoin d’utiliser des rôles, suivez la même approche. Vous devrez peut-être
injecter un RoleManager<T> (utilisez IdentityRole pour le type par défaut) pour
répertorier et gérer les rôles eux-mêmes.
Note : Dans les projets Blazor WebAssembly, vous devez fournir des API serveur pour
effectuer ces opérations (au lieu d’utiliser UserManager<T> ou RoleManager<T>
directement). Une application cliente Blazor WebAssembly gérerait les revendications
et/ou les rôles en appelant en toute sécurité les points de terminaison d’API exposés à
cet effet.
Guide de migration
La migration d’ASP.NET Web Forms et de fournisseurs universels vers ASP.NET Core
Identity nécessite plusieurs étapes :
Chacune de ces étapes est décrite en détail dans les sections suivantes.
la sur le site. Vous devez déclencher une page comme celle illustrée ci-dessous :
Cliquez sur le bouton « Appliquer des migrations » et les tables de base de données
nécessaires doivent être créées pour vous. En outre, les fichiers de migration doivent
apparaître dans votre projet, comme indiqué :
Vous pouvez exécuter la migration vous-même, sans exécuter l’application web, à l’aide
de cet outil en ligne de commande :
PowerShell
dotnet ef database update
Si vous préférez exécuter un script pour appliquer le nouveau schéma à une base de
données existante, vous pouvez scripter ces migrations à partir de la ligne de
commande. Exécutez cette commande pour générer le script :
PowerShell
La commande ci-dessus génère un script SQL dans le fichier de sortie auth.sql , qui
peut ensuite être exécuté sur la base de données souhaitée. Si vous rencontrez des
problèmes lors de l’exécution des commandes dotnet ef , assurez-vous que les outils EF
Core sont installés sur votre système.
Si vous avez des colonnes supplémentaires sur vos tables sources, vous devez identifier
le meilleur emplacement pour ces colonnes dans le nouveau schéma. En règle générale,
les colonnes trouvées sur la table aspnet_Membership doivent être mappées à la table
AspNetUsers . Les colonnes sur aspnet_Roles doivent être mappées à AspNetRoles .
Cela vaut également la peine d’envisager de placer des colonnes supplémentaires sur
des tables distinctes. Ainsi, les migrations futures n’auront pas besoin de tenir compte
de ces personnalisations du schéma d’identité par défaut.
Pour migrer vos utilisateurs de l’appartenance aux nouvelles tables d’identité, vous
devez suivre les étapes décrites dans la documentation. Après avoir suivi ces étapes et le
script fourni, vos utilisateurs devront modifier leur mot de passe la prochaine fois qu’ils
se connecteront.
Il est possible de migrer les mots de passe utilisateur, mais le processus est beaucoup
plus impliqué. Exiger des utilisateurs de mettre à jour leurs mots de passe dans le cadre
du processus de migration et les encourager à utiliser de nouveaux mots de passe
uniques est susceptible d’améliorer la sécurité globale de l’application.
C#
Microsoft.AspNetCore.Identity.UI référencés.
En outre, dans Program.cs vous devez voir l’intergiciel nécessaire configuré pour le site.
Plus précisément, UseAuthentication et UseAuthorization doivent être configurés et à
l’emplacement approprié.
C#
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for
production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
//app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
razor
@attribute [Authorize]
Si, de plus, vous refusiez l’accès sauf aux utilisateurs appartenant à un certain rôle, vous
migreriez pareillement ce comportement en ajoutant un attribut spécifiant un rôle :
razor
L’attribut [Authorize] fonctionne uniquement sur des composants @page qui sont
atteints via le routeur Blazor. L’attribut ne fonctionne pas avec les composants enfants,
qui doivent utiliser à la place AuthorizeView .
Si vous avez une logique dans la balise de page pour déterminer s’il faut afficher du
code à un utilisateur donné, vous pouvez la remplacer par le composant AuthorizeView .
Le composant AuthorizeView affiche sélectivement l’interface utilisateur en fonction de
l’autorisation que l’utilisateur a pour l’afficher. Il expose également une variable context
qui peut être utilisée pour accéder aux informations utilisateur.
razor
<AuthorizeView>
<Authorized>
<h1>Hello, @context.User.Identity.Name!</h1>
<p>You can only see this content if you are authenticated.</p>
</Authorized>
<NotAuthorized>
<h1>Authentication Failure!</h1>
<p>You are not signed in.</p>
</NotAuthorized>
</AuthorizeView>
vous permet de déterminer s’il est authentifié et s’il appartient à un rôle particulier. Si
vous devez évaluer une stratégie de façon procédurale, vous pouvez injecter une
instance de IAuthorizationService et appeler la méthode AuthorizeAsync sur celle-ci.
L’exemple de code suivant montre comment obtenir des informations utilisateur et
autoriser un utilisateur autorisé à effectuer une tâche restreinte par la stratégie content-
editor .
razor
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService
@code {
[CascadingParameter]
private Task<AuthenticationState> authenticationStateTask { get; set; }
if (user.Identity.IsAuthenticated)
{
// Perform an action only available to authenticated (signed-in)
users.
}
if (user.IsInRole("admin"))
{
// Perform an action only available to users in the 'admin'
role.
}
razor
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData"
DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
Résumé
Blazor utilise le même modèle de sécurité qu’ASP.NET Core, qui est ASP.NET Core
Identity. La migration de fournisseurs universels vers ASP.NET Core Identity est
relativement simple, en supposant qu’aucune personnalisation n’a été appliquée au
schéma de données d’origine. Une fois les données migrées, l’utilisation de
l’authentification et de l’autorisation dans les applications Blazor est bien documentée,
avec une prise en charge configurable et de programmation pour la plupart des
exigences de sécurité.
References
Introduction à Identity sur ASP.NET Core
Migrer de l’authentification d’appartenance ASP.NET vers ASP.NET Core 2.0
Identity
Migrer l’authentification et l’identité vers ASP.NET Core
Authentification et autorisation avec ASP.NET Core Blazor
Précédent Suivant
Migrer à partir d’ASP.NET Web Forms
vers Blazor
Article • 08/06/2023
Conseil
Ce contenu est un extrait du livre électronique, Blazor pour les développeurs ASP
NET Web Forms pour Azure, disponible dans la documentation .NET ou au format
PDF à télécharger gratuitement pour le lire hors connexion.
Télécharger le PDF
La migration d’une base de code à partir d’ASP.NET Web Forms vers Blazor est une
tâche fastidieuse qui nécessite une planification. Ce chapitre décrit le processus. Une
solution qui permet de faciliter la transition consiste à s’assurer que l’application
respecte une architecture multiniveau, où le modèle d’application (dans ce cas, Web
Forms) est distinct de la logique métier. Cette séparation logique des couches indique
clairement ce qui doit être déplacé vers .NET Core et Blazor.
Pour cet exemple, l’application eShop disponible sur GitHub est utilisée. eShop est un
service de catalogue qui fournit des capacités CRUD via l’entrée de formulaire et la
validation.
Pourquoi une application opérationnelle doit-elle être migrée vers Blazor ? Beaucoup de
fois, il n’y a pas besoin. ASP.NET Web Forms continuera d’être pris en charge pendant
de nombreuses années. Toutefois, la plupart des fonctionnalités fournies par Blazor sont
uniquement prises en charge sur une application migrée. Les fonctionnalités incluent :
Au moment de l’écriture, le modèle côté serveur ressemble plus Web Forms. La plupart
de ce chapitre se concentre sur le modèle d’hébergement côté serveur, car il est prêt
pour la production.
Créer un projet
Cette étape de migration initiale consiste à créer un projet. Ce type de projet est basé
sur les projets de style SDK de .NET et simplifie une grande partie de la réutilisable
utilisée dans les formats de projet précédents. Pour plus d’informations, consultez le
chapitre sur la Structure de projet.
Une fois le projet créé, installez les bibliothèques utilisées dans le projet précédent. Dans
les anciens projets Web Forms, vous avez peut-être utilisé le fichier packages.config pour
répertorier les packages NuGet requis. Dans le nouveau projet de style SDK,
packages.config a été remplacé par des éléments <PackageReference> dans le fichier
projet. L’un des avantages de cette approche est que toutes les dépendances sont
installées de manière transitive. Vous listez uniquement les dépendances de niveau
supérieur qui vous intéressent.
La plupart des dépendances que vous utilisez sont disponibles pour .NET, notamment
Entity Framework 6 et log4net. Si aucune version .NET ou .NET Standard n’est
disponible, la version du .NET Framework peut souvent être utilisée. Votre kilométrage
peut varier. Toute API utilisée qui n’est pas disponible dans .NET provoque une erreur de
runtime. Visual Studio vous informe de la présence de tels paquets. Une icône jaune
s’affiche sur le nœud Références du projet dans Explorateur de solutions.
Dans le projet eShop basé sur Blazor, vous pouvez voir les packages installés.
Auparavant, le fichier packages.config listait chaque package utilisé dans le projet, ce qui
entraînait une fichier de près de 50 lignes de long. Un extrait de code de packages.config
est :
XML
Le projet Blazor répertorie les dépendances dont vous avez besoin dans un élément
<ItemGroup> dans le fichier projet :
XML
<ItemGroup>
<PackageReference Include="Autofac" Version="4.9.3" />
<PackageReference Include="EntityFramework" Version="6.4.4" />
<PackageReference Include="log4net" Version="2.0.12" />
<PackageReference
Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="2.2.12"
/>
</ItemGroup>
Un package NuGet qui simplifie la durée de vie des développeurs Web Forms est le pack
de compatibilité Windows. Bien que .NET soit multiplateforme, certaines fonctionnalités
sont disponibles uniquement sur Windows. Les fonctionnalités spécifiques à Windows
sont disponibles en installant le pack de compatibilité. Parmi ces fonctionnalités, citons
le Registre, WMI et les services d’annuaire. Le package ajoute environ 20 000 API et
active de nombreux services avec lesquels vous êtes peut-être déjà familiarisé. Le projet
eShop ne nécessite pas le pack de compatibilité ; mais si vos projets utilisent des
fonctionnalités spécifiques à Windows, le package facilite les efforts de migration.
C#
/// <summary>
/// Track the machine name and the start time for the session inside the
current session
/// </summary>
protected void Session_Start(Object sender, EventArgs e)
{
HttpContext.Current.Session["MachineName"] =
Environment.MachineName;
HttpContext.Current.Session["SessionStartTime"] = DateTime.Now;
}
/// <summary>
/// https://autofaccn.readthedocs.io/en/latest/integration/webforms.html
/// </summary>
private void ConfigureContainer()
{
var builder = new ContainerBuilder();
var mockData =
bool.Parse(ConfigurationManager.AppSettings["UseMockData"]);
builder.RegisterModule(new ApplicationModule(mockData));
container = builder.Build();
_containerProvider = new ContainerProvider(container);
}
if (!mockData)
{
Database.SetInitializer<CatalogDBContext>
(container.Resolve<CatalogDBInitializer>());
}
}
LogicalThreadContext.Properties["requestinfo"] = new
WebRequestInfo();
_log.Debug("Application_BeginRequest");
}
}
C#
using eShopOnBlazor.Models;
using eShopOnBlazor.Models.Infrastructure;
using eShopOnBlazor.Services;
using log4net;
using System.Data.Entity;
using eShopOnBlazor;
// add services
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
if (builder.Configuration.GetValue<bool>("UseMockData"))
{
builder.Services.AddSingleton<ICatalogService, CatalogServiceMock>();
}
else
{
builder.Services.AddScoped<ICatalogService, CatalogService>();
builder.Services.AddScoped<IDatabaseInitializer<CatalogDBContext>,
CatalogDBInitializer>();
builder.Services.AddSingleton<CatalogItemHiLoGenerator>();
builder.Services.AddScoped(_ => new
CatalogDBContext(builder.Configuration.GetConnectionString("CatalogDBContext
")));
}
new LoggerFactory().AddLog4Net("log4Net.xml");
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
ConfigDataBase(app);
if (initializer != null)
{
Database.SetInitializer(initializer);
}
}
}
app.Run();
Dans l’application eShop d’origine, il existe une configuration pour la gestion des
sessions. Étant donné que Blazor côté serveur utilise ASP.NET Core SignalR pour la
communication, l’état de session n’est pas pris en charge, car les connexions peuvent se
produire indépendamment d’un contexte HTTP. Une application qui utilise l’état de
session nécessite une nouvelle architecture avant de l’exécuter en tant qu’application
Blazor.
C#
...
app.UseStaticFiles();
...
Par exemple, la vue détails comprend trois fichiers dans le projet Web Forms :
Details.aspx, Details.aspx.cs et Details.aspx.designer.cs. Lors de la conversion en Blazor, le
code-behind et le balisage sont combinés en Details.razor. La compilation Razor
(équivalente à ce qui se trouve dans les fichiers .designer.cs) est stockée dans le
répertoire obj et n’est pas, par défaut, visible dans Explorateur de solutions. La page
Web Forms se compose du balisage suivant :
ASP.NET (C#)
<div class="container">
<div class="row">
<asp:Image runat="server" CssClass="col-md-6 esh-picture"
ImageUrl='<%#"/Pics/" + product.PictureFileName%>' />
<dl class="col-md-6 dl-horizontal">
<dt>Name
</dt>
<dd>
<asp:Label runat="server" Text='<%#product.Name%>' />
</dd>
<dt>Description
</dt>
<dd>
<asp:Label runat="server"
Text='<%#product.Description%>' />
</dd>
<dt>Brand
</dt>
<dd>
<asp:Label runat="server"
Text='<%#product.CatalogBrand.Brand%>' />
</dd>
<dt>Type
</dt>
<dd>
<asp:Label runat="server"
Text='<%#product.CatalogType.Type%>' />
</dd>
<dt>Price
</dt>
<dd>
<asp:Label CssClass="esh-price" runat="server"
Text='<%#product.Price%>' />
</dd>
<dt>Picture name
</dt>
<dd>
<asp:Label runat="server"
Text='<%#product.PictureFileName%>' />
</dd>
<dt>Stock
</dt>
<dd>
<asp:Label runat="server"
Text='<%#product.AvailableStock%>' />
</dd>
<dt>Restock
</dt>
<dd>
<asp:Label runat="server"
Text='<%#product.RestockThreshold%>' />
</dd>
<dt>Max stock
</dt>
<dd>
<asp:Label runat="server"
Text='<%#product.MaxStockThreshold%>' />
</dd>
</dl>
</div>
<div class="form-actions no-color esh-link-list">
<a runat="server" href='<%# GetRouteUrl("EditProductRoute", new
{id =product.Id}) %>' class="esh-link-item">Edit
</a>
|
<a runat="server" href="~" class="esh-link-item">Back to list
</a>
</div>
</div>
</asp:Content>
C#
using eShopLegacyWebForms.Models;
using eShopLegacyWebForms.Services;
using log4net;
using System;
using System.Web.UI;
namespace eShopLegacyWebForms.Catalog
{
public partial class Details : System.Web.UI.Page
{
private static readonly ILog _log =
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().Declari
ngType);
this.DataBind();
}
}
}
Lorsqu’elle est convertie en Blazor, la page Web Forms se traduit par le code suivant :
razor
@page "/Catalog/Details/{id:int}"
@inject ICatalogService CatalogService
@inject ILogger<Details> Logger
<h2 class="esh-body-title">Details</h2>
<div class="container">
<div class="row">
<img class="col-md-6 esh-picture"
src="@($"/Pics/{_item.PictureFileName}")">
<dd>
@_item.Name
</dd>
<dt>
Description
</dt>
<dd>
@_item.Description
</dd>
<dt>
Brand
</dt>
<dd>
@_item.CatalogBrand.Brand
</dd>
<dt>
Type
</dt>
<dd>
@_item.CatalogType.Type
</dd>
<dt>
Price
</dt>
<dd>
@_item.Price
</dd>
<dt>
Picture name
</dt>
<dd>
@_item.PictureFileName
</dd>
<dt>
Stock
</dt>
<dd>
@_item.AvailableStock
</dd>
<dt>
Restock
</dt>
<dd>
@_item.RestockThreshold
</dd>
<dt>
Max stock
</dt>
<dd>
@_item.MaxStockThreshold
</dd>
</dl>
</div>
</div>
@code {
private CatalogItem _item;
[Parameter]
public int Id { get; set; }
_item = CatalogService.FindCatalogItem(Id);
}
}
Notez que le code et le balisage se trouvent dans le même fichier. Tous les services
requis sont rendus accessibles avec l’attribut @inject . Conformément à la directive
@page , cette page est accessible à l’itinéraire Catalog/Details/{id} . La valeur de
l’espace réservé {id} de l’itinéraire a été limitée à un entier. Comme décrit dans la
section routage, contrairement à Web Forms, un composant Razor indique explicitement
son itinéraire et tous les paramètres inclus. De nombreux contrôles Web Forms peuvent
ne pas avoir d’équivalents exacts dans Blazor. Il existe souvent un extrait de code HTML
équivalent qui servira le même objectif. Par exemple, le contrôle <asp:Label /> peut
être remplacé par un élément <label> HTML.
ASP.NET
<div class="form-group">
<label class="control-label col-md-2">Name</label>
<div class="col-md-3">
<asp:TextBox ID="Name" runat="server" CssClass="form-control">
</asp:TextBox>
<asp:RequiredFieldValidator runat="server" ControlToValidate="Name"
Display="Dynamic"
CssClass="field-validation-valid text-danger" ErrorMessage="The
Name field is required." />
</div>
</div>
razor
<div class="form-group">
<label class="control-label col-md-2">Name</label>
<div class="col-md-3">
<InputText class="form-control" @bind-Value="_item.Name" />
<ValidationMessage For="(() => _item.Name)" />
</div>
</div>
...
</EditForm>
L’extrait de code suivant montre comment le projet eShop Web Forms utilise web.config
pour stocker les valeurs de configuration :
XML
<configuration>
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection,
EntityFramework, Version=6.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="CatalogDBContext" connectionString="Data Source=
(localdb)\MSSQLLocalDB; Initial
Catalog=Microsoft.eShopOnContainers.Services.CatalogDb; Integrated
Security=True; MultipleActiveResultSets=True;"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="UseMockData" value="true" />
<add key="UseCustomizationData" value="false" />
</appSettings>
</configuration>
Il est courant que des secrets, tels que les chaînes de connexion de base de données,
soient stockés dans web.config. Les secrets sont inévitablement conservés dans des
emplacements non sécurisés, tels que le contrôle de code source. Avec Blazor sur
ASP.NET Core, la configuration XML précédente est remplacée par le code JSON
suivant :
JSON
{
"ConnectionStrings": {
"CatalogDBContext": "Data Source=(localdb)\\MSSQLLocalDB; Initial
Catalog=Microsoft.eShopOnContainers.Services.CatalogDb; Integrated
Security=True; MultipleActiveResultSets=True;"
},
"UseMockData": true,
"UseCustomizationData": false
}
JSON est le format de configuration par défaut. Toutefois, ASP.NET Core prend en
charge de nombreux autres formats, notamment XML. Il existe également plusieurs
formats pris en charge par la communauté.
C#
if (builder.Configuration.GetValue<bool>("UseMockData"))
{
builder.Services.AddSingleton<ICatalogService, CatalogServiceMock>();
}
else
{
builder.Services.AddScoped<ICatalogService, CatalogService>();
builder.Services.AddScoped<IDatabaseInitializer<CatalogDBContext>,
CatalogDBInitializer>();
builder.Services.AddSingleton<CatalogItemHiLoGenerator>();
builder.Services.AddScoped(_ => new
CatalogDBContext(builder.Configuration.GetConnectionString("CatalogDBContext
")));
}
.NET Core, cela n’est pas pris en charge. La chaîne de connexion doit être fournie.
L'accès à la base de données s'est fait de manière synchrone. Bien que cela
fonctionne, la scalabilité peut souffrir. Cette logique doit être déplacée vers un
modèle asynchrone.
Bien qu’il n’y ait pas la même prise en charge native de la liaison de jeu de données,
Blazor offre une flexibilité et une puissance avec sa prise en charge C# dans une page
Razor. Par exemple, vous pouvez effectuer des calculs et afficher le résultat. Pour plus
d’informations sur les modèles de données dans Blazor, consultez le chapitre Accès aux
données.
Modifications architecturales
Enfin, il existe quelques différences architecturales importantes à prendre en compte
lors de la migration vers Blazor. La plupart de ces modifications s’appliquent à tout ce
qui est basé sur .NET Core ou ASP.NET Core.
Étant donné que Blazor s’appuie sur .NET Core, il existe des considérations à prendre en
compte pour garantir la prise en charge sur .NET Core. Parmi les principales
modifications, citons la suppression des fonctionnalités suivantes :
Plusieurs AppDomains
Communication à distance
Sécurité d'accès du code
Transparence de la sécurité
Pour plus d’informations sur les techniques permettant d’identifier les modifications
nécessaires pour prendre en charge l’exécution sur .NET Core, consultez Amener votre
code de .NET Framework vers .NET Core.
ASP.NET Core est une version réimaginée de ASP.NET et a des modifications qui
peuvent ne pas sembler évidentes initialement. Les principales modifications sont les
suivantes :
pool de threads.
Conclusion de la migration
À ce stade, vous avez vu de nombreux exemples de ce qu’il faut faire pour déplacer un
projet Web Forms vers Blazor. Pour obtenir un exemple complet, consultez le projet
eShopOnBlazor .
Précédent