Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    View Cyril Durand's profile on LinkedIn

    hit counters

Dynamic Expression personnalise : ProfileExpressionBuilder avec ASP.net 2.0

Avec ASP.net 2.0 il est possible de faire d'utiliser des "Dynamic expressions" dans les pages .aspx. Qu'est-ce que c'est ? Voyons un exemple :

<asp:label runat="server" id="lbl1" text="<%$ AppSettings:MyKey %>" />

Découverte des $-expressions

Avec ASP.net 2.0 vous pouvez directement accédez aux valeurs AppSettings en utilisant la syntaxe <%$ AppSettings : keyName %>, les dynamics expressions, que j'appellerais $-expressions, est l'utilisation de la syntaxe <%$. Par défaut il existe 3 $-expressions :

Syntax

Description

AppSettings:[Attribute]

Returns the value of the specified setting from the <appSettings> section of the configuration file.

ConnectionStrings:[Entry],[Attribute]

Returns the value of the specified attribute of the given entry in the <connectionStrings> section of the configuration file

Resources:[ResourceFile],[ResourceName]

Returns the value of the specified global resource.

Ce qui est intéressant c'est qu'on peut créer nos propres $-expression. En guise d'exemple faisons un $-expression permettant de récupérer les valeurs du profile.

Création d'un $-expression personnalisé : ProfileExpressionBuilder

Explication du principe général

Tout d'abord nous devons créer une classe qui hérite de ExpressionBuilder :

[ExpressionPrefix("Profile")] public class ProfileExpressionBuilder : ExpressionBuilder { public override object ParseExpression(string expression, Type propertyType, ExpressionBuilderContext context) { /// ... } public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) { // ... } }

On voit que l'on a décoré notre classe de l'attribut ExpressionPrefix, cet attribut est optionnel mais vous permet de savoir sur quelle $-expression l'ExpressionBuilder travail. On verra plus tard qu'on associe le $-expression avec l'ExpressionBuilder dans le web.config.

Ensuite on a une méthode ParseExpression qui prend en paramètre :

  • un string qui contiendra dans notre exemple le nom de la propriété du profile, ce string contient tous ce qui suit le <%$ prefix: expression %>
  • le type de la propriété sur laquelle est associé notre $-expression. En fait un $-expression peut être utilisé seulement pour renseigner des propriétés de contrôles serveurs, si vous mettez <%$ Profile:City %> au millieu de la page cela ne fonctionnera pas, il faut obligatoirement qu'il assigne une propriété d'un contrôle runat="server" c'est à dire <prefix:controlName runat="server" prop="<%$ Profile:City %>" />. On verra plus tard pourquoi lorsque j'expliquerais le fonctionnement des $-expressions.
  • Le contexte qui permet de récupérer le nom de la page sur laquelle on utilise notre $-expression.

Le résultat de cette méthode est ensuite passé à la méthode GetCodeExpression qui elle prend en paramètre :

  • les informations du contrôle sur lequel est utilisé ce $-expression.
  • L'object retourné par la méthode ParseExpression
  • Le context.

Le résultat de cette méthode doit être une expressionCodeDom, c'est à dire qu'à partir de cet objet, ASP.net doit être capable de générer du code qui permet de récupérer la propriété voulue du Profile.

Un peu de code

Maintenant que l'on a vu rapidement comment cela fonctionne, écrivons un peu de code :-) Dans notre cas la méthode ParseExpression devra retourner seulement le nom de la propriété du profile voulue, il suffit alors de faire :

public override object ParseExpression(string expression, Type propertyType, ExpressionBuilderContext context) { return expression; }

La méthode GetCodeExpression devra elle retourner un noeud CodeDom permettant de générer :

System.Web.HttpContext.Current.Profile.GetPropertyValue(propertyName);

Mais dans la plupart des cas on génère un appel vers une méthode static car on a souvent plus d'une ligne de code à générer. Rajoutons alors une méthode static GetProperty qui retournera la valeur du profile voulue.

public static Object GetProperty(String propertyName) { return HttpContext.Current.Profile.GetPropertyValue(propertyName); }

Il nous faut maintenant écrire le code CodeDom qui va générer le code permettant d'appeler la méthode statique GetProperty :

public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) { String propertyName = (String)parsedData; CodePrimitiveExpression prim = new CodePrimitiveExpression(propertyName); CodeExpression[] args = new CodeExpression[1] { prim }; CodeTypeReferenceExpression refType = new CodeTypeReferenceExpression(base.GetType()); return new CodeMethodInvokeExpression(refType, "GetProperty", args); }

A partir de là notre ExpressionBuilder est prêt, il ne nous reste plus qu'à l'enregistrer dans le Web.config, rien de plus simple :

<compilation> <expressionBuilders> <add expressionPrefix="Profile" type="ProfileExpressionBuilder"/> </expressionBuilders> </compilation>

Vous pouvez maintenant utiliser ce code pour afficher le contenu du profile :

<asp:Label ID="lbl1" runat="server" Text="<%$ Profile:City %>"></asp:Label>

Support des "no-compile Pages"

ASP.net 2.0 permet de ne pas compiler automatiquement certaines pages, je ne vais pas rentrer en détails dans le fonctionnement des "no-compile Pages" mais c'est possible en définissant l'attribut CompilationMode à Never (l'attribut CompilationMode sur MSDN). Bref, dans ce cas vous devez surchargé la méthode EvaluateExpression, je détail pas le code car les "no-compiles pages" sont très rarement utile. Vous devez également surcharger une propriété pour spécifier que votre $-expression est utilisable avec ce type de page :

public override object EvaluateExpression(object target, BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) { return GetProperty((String)parsedData); } public override bool SupportsEvaluate { get { return true; } }

 Cet exemple provient du livre "ASP.net 2.0 Applications - Advanced Topics" de Dino Esposito, vous pouvez retrouver le code complet sur aspfr.com : Accéder aux propriétés du Profile via un ExpressionBuilder personnalisé

Fonctionnement des $-expression

La majorité du code de notre ExpressionBuilder sera executé lors de la pré-compilation des pages, en effet lorsque le parseur ASP.net (ie : la classe PageBuildProvider) tombe sur une $-expression lors de la génération du code final de la page, il regarde quelle est le préfixe (AppSettings, Profile, ...) cherche l'ExpressionBuilder associé dans le web.config, appel la méthode ParseExpression puis génére le code à partir de l'expression CodeDom retourné par la méthode GetCodeExpression et enfin écrit le code dans la méthode surchargé __BuildControlTree de la Page, les $-expression sont donc appelés lors de l'appel de la méthode __BuildControlTree c'est à dire au tout début du cycle de vie de la page.

Ressource :

Il n'existe malheureusement pas beaucoup d'article parlant de la pré-compilation des pages ASP.net

Dino Esposito en parle très bien sur le bouquin "ASP.net 2.0 Applications - Advanced Topics"

couverture du livre de dino

Il y a heureusement la documentation la plus complete sur ASP.net : Reflector for .NET

Si vous avez des questions sur le fonctionnement des $-expression les commentaires sont là pour ça ;-)

PS : vous avez vu ? pas une ligne de JavaScript !!! ;-)

Posted: jeudi 14 décembre 2006 16:48 par cyril
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

neodante a dit :

Hum hum je sens que je vais me prendre ce buiquin-là .. sinon super post :p

# décembre 14, 2006 19:35

cyril a dit :

Dino a écrit 3 bouquins

Introducing ASP.net 2.0      : pour découvrir ASP.net

ASP.net 2.0 Core Reference   : pour se servir d'asp.net

ASP.net 2.0 Advanced Topics  : pour comprendre ASP.net

j'ai lu les 2 premiers et c'est une collection que TOUS les developpeurs ASP.net devraient lire ...

Le peu que j'ai lu du dernier bouquin est vraiment celui que je préfére, avec Reflector c'est la seule solution qui permet de comprendre ASP.net.

# décembre 14, 2006 21:42

Poppyto a dit :

Ah yes ! J'en avais parlé dans le Programmez spécial .net (pour faire les sites multilingues). Et effectivement la doc est pauvre à ce niveau !

# décembre 15, 2006 09:11
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Disparition de variables de session PHP après une redirection ? par MadMatt le il y a 9 heures et 27 minutes

- [MOSS 2007] Publier ses formulaires InfoPath via feature par Adrien Siffermann le il y a 12 heures et 34 minutes

- Imagine Cup 2008 - Paris - Les résultats par TheSaib .NET blog le il y a 13 heures et 56 minutes

- L'Egypte accueille Imagine Cup 2009 par Code is poetry le il y a 14 heures et 8 minutes

- PowerShell : Mise en ligne de fonctions intéressantes pour SharePoint par Blog Technique de Romelard Fabrice le il y a 15 heures et 16 minutes

- Raccourcis clavier et CRM 4 par Clark, C#, MSCRM, SBS le il y a 19 heures et 21 minutes

- [Silverlight] Comment échanger des données entre une application Silverlight et une page ASP.NET via cookies ? par Thomas Lebrun le il y a 19 heures et 57 minutes

- SharePoint 2007 : Trouver les fichiers CheckOut dans une librairie de document par Philippe Sentenac [MVP SharePoint] le il y a 22 heures et 25 minutes

- [Open XML] Travailler avec Open XML : Linq To XML (Partie 2 - Requêtes/XPath) par Julien Chable le 07-08-2008, 02:05

- [Open XML] Travailler avec Open XML : Linq To XML (Partie 1 - Namespace) par Julien Chable le 07-08-2008, 00:44