Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Azra [Florent Santin]

.Net, X'Net, aucun lien de parenté V2.0

Actualités

  • MSN Alerts
    View Florent Santin's profile on LinkedIn
    MS Days - MSDN et TechNet Tour spécial Dev
Gestion des menus en ASP.NET 2.0

Tout site internet avec un minimum de contenu nécessite une gestion de la navigation claire et pratique. Pour répondre à ce pré-requis, de nouveaux contrôles ont fait leur apparition dans ASP.NET 2.0. Mais derrière ceux-ci, comme derrière la plupart des nouveaux contrôles, c’est toute une logique de développement qui a fait son apparition : le développement par providers.

Parmi les contrôles de navigation d’ASP.NET 2.0, vous pouvez donc trouver au niveau de la boite à outils de Visual Studio 2005 :
- Le TreeView, permettant d’afficher des données hiérarchiques sous forme d’arbre,
- Le contrôle menu, pour créer des menus dynamiques ou statiques, verticaux ou horizontaux, contextuels ou non,
- Le SiteMapPath, sorte de fil d’Ariane qui permet de situer la page où se trouve l’utilisateur dans le cas d’une arborescence sous plusieurs niveaux.

Les contrôles TreeView et Menu nécessitent d’être liés directement à une source de données pour fonctionner, celle ci ayant pour rôle de définir l’arborescence du site. La configuration par défaut repose sur un fichier au format XML, de type « *.sitemap ». Voici un exemple de fichier « web.sitemap » (web étant le nom du fichier défini de base) :


<?xml version="1.0" encoding="utf-8" ?> <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" > <siteMapNode url="" title="racine" description=""> <siteMapNode url="~/page1.aspx" title="Page 1" description="La page 1" /> <siteMapNode url="~/page2.aspx" title="Page 2" description="La page 2" /> <siteMapNode url="" title="Admin" description="La section d’administration"> <siteMapNode url="~/privee/page3.aspx" title="Page 3" description="La page 3" /> <siteMapNode url="~/privee/page4.aspx" title="Page 4" description="La page 4" /> </siteMapNode> </siteMapNode> </siteMap>

Comme vous le voyez, ce fichier est composé d’un ensemble de nœuds représentant une arborescence contenant des éléments sur plusieurs niveaux. L’attribut « url » présente la page de navigation cible, « titre » le nom à afficher et « description » est utilisée la plupart du temps comme « tooltip ».

Sans aucune modification au niveau des fichiers de configuration du site internet, et juste en liant un contrôle de type TreeView à une source de données de type « SiteMapDataSource », le résultat suivant est obtenu :

Comme beaucoup de choses dans ASP.NET 2.0, il est très facile de rendre votre menu multi-langues. Je n’entrerai pas dans les détails (un article complet est consacré à la localisation dans ce numéro), mais la liaison entre les données à traduire et les traductions (présentes dans des fichiers de ressources) se fait au niveau du fichier web.sitemap. Il vous suffit d’y activer la prise en charge de la localisation (enableLocalization=true) et d’y définir des clés représentant les relations menu / fichier de ressources.

<?xml version="1.0" encoding="utf-8" ?> <siteMap xmlns="…" enableLocalization="true" > <siteMapNode url="~/Default.aspx" title="racine" resourceKey="root"> <siteMapNode url="~/page1.aspx" title="Page 1" resourceKey="page1" /> <siteMapNode url="~/page2.aspx" title="Page 2" resourceKey="page2" /> </siteMapNode> </siteMap>

Dans cet exemple, pour modifier le titre du nœud racine il faudra définir dans un fichier de ressources une valeur pour la clé « root.title » sans quoi la valeur par défaut « racine » sera utilisée.

Maintenant, pour aller plus loin, il peut être intéressant d’avoir un menu qui s’affiche en fonction des droits utilisateurs. Dans l’exemple précédant, on remarque qu’une sous partie du site est liée à l’administration. ASP.NET 2.0 offre justement, grâce à une option avancée du provider de menu de base, la possibilité d’afficher le menu en fonction de l’appartenance ou non de l’utilisateur à un groupe de sécurité. Quelques modifications sont cependant nécessaires au niveau du fichier de configuration de l’application « web.config » afin d’activer cette fonctionnalité avancée.

Tout d’abord, il faut savoir que la gestion des rôles applicatifs en ASP.NET 2.0 s’effectue grâce à un autre provider : le RoleManager. Il est donc nécessaire d’activer celui-ci afin de le rendre utilisable par le provider de menu. Par défaut, le RoleManager utilise le SqlRoleProvider gérant ainsi ses groupes utilisateurs dans une base de données SQL.

<roleManager enabled="true" />

Ensuite, toujours au niveau du « web.config », il est nécessaire d’activer l’option d’affichage partiel de menu en fonction des droits. Pour ceci, vous devez redéfinir le provider de menu présent initialement dans le web.config du répertoire CONFIG du Framework et activer l’option « securityTrimmingEnabled ».

<siteMap defaultProvider="AspFrMapProvider" enabled="true"> <providers> <add siteMapFile="web.sitemap" name="AspFrMapProvider" type="System.Web.XmlSiteMapProvider" securityTrimmingEnabled="true" /> </providers> </siteMap>

Enfin pour terminer, il reste à définir les droits d’accès pour chaque groupe applicatif, d’un point de vue sécurité, en définissant les règles d’accès pour les groupes d’utilisateurs. Dans notre exemple, il suffit de créer un fichier de configuration « web.config » dans le répertoire « admin » et d’y autoriser uniquement les utilisateurs membres du groupe « admin ».

<?xml version="1.0" encoding="utf-8"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <system.web> <authorization> <allow roles="admin" /> <deny users="*" /> </authorization> </system.web> </configuration>

Quelques points importants sont à prendre en considération lorsque vous activez le « securityTriming ». Tout d’abord, au niveau du fichier .sitemap, il est nécessaire d’avoir tous les nœuds complètement renseignés. Si vous laissez des nœuds vides (par exemple sans spécifier l’URL), leur niveau d’accès ne pourra pas être évalué par la gestion de la sécurité et le nœud et l’ensemble de ses nœuds enfant ne seront pas affichés dans le menu.
Par contre, si vous spécifiez des liens vers des fichiers physiquement inexistants, ils seront automatiquement visibles pour tout le monde, malgré le fait que le lien soit mort.
A l’opposé, si vous souhaitez ajouter des liens externes à votre site dans votre menu, vous devez spécifier explicitement les groupes ayant accès grâce à l’attribut « roles » présent dans les nœuds du fichier siteMap. Par exemple pour ajouter un accès à CodeS-SourceS.com a tout le monde et a Aspfr.com uniquement aux administrateurs, il faudra écrire le web.sitemap tel quel :

<?xml version="1.0" encoding="utf-8" ?> <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" > <siteMapNode url="~/Default.aspx" title="racine"> <siteMapNode url="~/page1.aspx" title="Page 1 /> <siteMapNode url="~/page2.aspx" title="Page 2" /> <siteMapNode url="http://www.codes-sources.com" title="Codes-Sources" roles="*" /> <siteMapNode url="~/admin/default.aspx" title="Admin"> <siteMapNode url="~/admin/page3.aspx" title="Page 3" /> <siteMapNode url="~/admin/page4.aspx" title="Page 4" /> <siteMapNode url="http://www.aspfr.com" title="aspFr" roles="admin" /> </siteMapNode> </siteMapNode> </siteMap>

Vous obtiendrez ainsi automatiquement le résultat suivant :

 

Rentrons maintenant plus en détails dans le fonctionnement du système de navigation afin d’étendre ou de modifier ses fonctionnalités. Tout d’abord, il faut savoir qu’en ASP.NET 2.0, l’arborescence d’un site est représentée en mémoire par un ensemble de nœuds « SiteMapNode » imbriqués contenant les informations propres à chaque page: « url », « titre de la page », « nœuds précédant/suivants », « nœud parent » etc.

Le Framework .NET 2.0 propose une API qui offre la possibilité de manipuler facilement les informations contenues dans cet ensemble de nœuds. Les contrôles de navigation présents dans ASP.NET 2.0 se basent d’ailleurs sur celle-ci pour fonctionner. D’un point de vue code, elle est matérialisée par une classe statique « SiteMap » qui permet notamment grâce à la propriété « CurrentNode » de récupérer le nœud d’informations définissant la page courante.

 

En vous appuyant sur cette classe statique, vous pouvez donc facilement créer des contrôles graphiques pour gérer votre système de navigation ou d’affichage de la navigation. On peut imaginer par exemple un contrôle permettant d’accéder à la page suivante ou précédente, comportement très fréquemment mis en place dans les sites Internet.

Les données représentant la structure de navigation de l’application sont donc conservées en mémoire et chargées à la demande de l’application par un provider. Celui-ci est donc en charge de la récupération des données et de leur mise en mémoire, d’une manière exploitable par l’API.

Un seul provider est présent dans le Framework 2.0, le « XmlSiteMapProvider » qui est capable d’extraire les données dans un fichier XML respectant un certain schéma. Si vous ne spécifiez pas de provider, c’est donc celui-ci qui sera utilisé par défaut.

Pour aller plus loin, ASP.NET 2.0 offre évidemment la possibilité de créer vos propres providers dans le but de répondre à divers besoins : gestion du menu en base de données, dans un format de fichier différent de l’XML, création de menu de manière dynamique, adaptation à un modèle de définition d’arborescence existant etc.…

Si vous souhaitez réaliser votre propre provider, il vous suffit de créer une classe héritant de la classe abstraite « SiteMapProvider ». Le fait d’hériter de cette classe vous force à respecter un contrat de communication qui rendra votre provider compatible avec tous les contrôles de navigation.
A noter qu’il existe une classe abstraite « StaticSiteMapProvider » qui hérite de la classe « SiteMapProvider », cette classe étant une version simplifiée de la classe « SiteMapProvider », vous pouvez donc utiliser soit l’une soit l’autre. Notons que XmlSiteMapProvider, le provider XML par défaut, hérite justement de StaticSiteMapProvider.

 

public class CSProvider : StaticSiteMapProvider { public override void Initialize(string name, System.Collections.Specialized.NameValueCollection attributes) { base.Initialize(name, attributes); string val = attributes["val"]; } public override SiteMapNode BuildSiteMap() { //création de l'arborescence //retourne l’élément racine } protected override SiteMapNode GetRootNodeCore() { //retourne l’élément racine } }

Une fois votre provider réalisé, il vous suffit de configurer votre application pour qu’elle l’utilise à la place du provider par défaut. Tout ceci se passe au niveau du fichier de configuration « Web.config » :

<siteMap defaultProvider="MonCSProvider" enabled="true"> <providers> <add name="MonCSProvider" type="CSProvider" val=”test”/> </providers> </siteMap>

Vous pouvez facilement ajouter des attributs de paramétrage au niveau de l’enregistrement de votre provider et les prendre en compte dans votre code (« val » dans l’exemple précédant). Ceci pour prouver que la logique de l’implémentation est sans limites à partir du moment où vous respectez le modèle de développement défini par la classe abstraite.

Comme vous avez pu le constater, la gestion de la navigation est vraiment simplifiée dans ASP.NET 2.0. Grâce aux contrôles et au provider déjà présent, il vous suffit de définir l’arborescence de votre site une seule fois dans un fichier XML et le Framework s’occupera de toute la gestion de l’affichage. De plus, si vous souhaitez aller plus loin, ASP.NET 2.0 offre un modèle de développement totalement extensible à tous les niveaux, que cela soit coté gestion des données ou affichage.

 

(Article parut dans le hors serie Programmez! 100% .NET, début 2006).

Posted: vendredi 6 octobre 2006 15:37 par azra
Classé sous :
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

themit a dit :

Marrant, tu reprends tes archives :)

Tu manques d'inspiration :D

bon je sors ...

PS : nikel ton article, manque juste un petit plus sur les XMLdatasource et les ASP:menu
# octobre 6, 2006 18:34

azra a dit :

Enf***** Renaud :P
# octobre 6, 2006 18:41
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Sortie de Silverlight 2 et de Flash player 10 par Nix's Blog le il y a 15 heures et 36 minutes

- Installation Silverlight RC0 et final ... par #Rui le il y a 16 heures et 28 minutes

- TCB : Que faire en salle blanche ? par The Mit's Blog le il y a 16 heures et 57 minutes

- Debug : Make Object ID - Comment connaitre l'état d'une variable lorsque celle-ci n'est pas accessible dans le scope courant par Atteint de JavaScriptite Aiguë [Cyril Durand] le 10-14-2008, 21:42

- IIS7 : Configuration des handlers pour l'upload de fichier - interdire certains fichiers de s'exécuter | accéder à des fichiers .cs, .aspx par Atteint de JavaScriptite Aiguë [Cyril Durand] le 10-14-2008, 19:49

- Microsoft annonce le nom commercial de Windows 7 par Code is poetry le 10-14-2008, 12:07

- [Silverlight] Téléchargez la version finale (et les outils associés) dès maintenant ! par Thomas Lebrun le 10-14-2008, 10:37

- Vilain bug avec IQueryable et la syntaxe yield : System.BadImageFormatException "An attempt was made to load a program with an incorrect format. (Exce... par Matthieu MEZIL le 10-14-2008, 07:48

- SQL Server 2008 : Un livre en cours de préparation ! par SQL Server vu par Christian Robert le 10-13-2008, 22:56

- IIS7 : à quel pool d'application correspond le processus w3wp.exe par Atteint de JavaScriptite Aiguë [Cyril Durand] le 10-13-2008, 21:59