Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Atteint de JavaScriptite Aiguë [Cyril Durand]

Expert ASP.net Ajax et WCF, Cyril Durand parle dans son blog de point techniques sur ASP.net, ASP.net Ajax, JavaScript, WCF et .net en général. Cyril est également consultant indépendant, n'hésitez pas à le contacter pour de l'assistance sur vos projets

Actualités

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

    N'hésitez pas à me contacter pour vos projets .net : architecture, accompagnement, formation, ...

    View Cyril Durand's profile on LinkedIn
    hit counters


    Expertise Commerce server et BizTalk

Passer des variables entre UserControl / Page / MasterPage

Question :

Comment communiquer entre la page et un UserControl ? C'est à dire passer des variables ou appeler des méthodes du UserControl à partir de la page ou réciproque.

Si je devais faire un top des questions les plus posés sur le forum d'aspfr, cette question arriverait en deuxième position derrière les problèmes liés aux contrôles dynamiques.

Réponse :

Il y a plusieurs solutions à ce problème.

Par une variable session :

La plus simple à mettre en œuvre consiste à passer par une variable session

public Tutorial tuto { get { return Session["Tuto"] as Tutorial; } set { Session["Tuto"] = value; } }

Si on ne veut pas mettre la variable en session on peut aussi utiliser le dictionnaire de page, la propriété sera donc définit seulement pour la requête en cours.

public Tutorial tuto { get { return Page.Items["Tuto"] as Tutorial; } set { Page.Items["Tuto"] = value; } }

En utilisant cette solution je vous conseille d'avoir une convention de nommage au niveau des clés afin d'éviter tout conflit. Vous pouvez aussi utiliser une enum comme ca aucun risque de conflit.

Je conseille cette solution pour des petits projets ou en solution temporaire pour faire des tests.

Par héritage :

J'aime avoir un framework associé au site sur lequel je travaille. Ma solution ressemble donc à ca :

Untitled

Ainsi dans votre classe Page de base vous pouvez rajouter la propriété

public class Page { private Tutorial _currentTutorial; public Tutorial CurrentTutorial { get { return _currentTutorial; } set { _currentTutorial = value; } } // ... } public class UserControl { public virtual new WebSite10.Web.UI.Page Page { get { return (WebSite10.Web.UI.Page)base.Page; } } // ... }

Il faudra alors hériter vos pages de WebSite10.Web.UI.Page et vos contrôles utilisateur de WebSite10.Web.UI.UserControl. La propriété marqué avec le mot clé new permet d'éviter d'avoir besoin de caster la propriété Page en WebSite10.Web.UI.Page, cela permet d'avoir un accès direct à la propriété Page.Tutorial. On peut faire la même chose en VB.

Cette solution est idéale si la plupart de vos pages utilisent cette propriété.

Par une interface :

On peut définir une interface que l'on implémente sur une Page ou UserControl

public interface ITutorial { Tutorial CurrentTutorial { get;set; } }

Dans la page ou l'UserControl vous pouvez caster la page en ITutorial pour accéder à la propriété CurrentTutorial.

((ITutorial)this.Page).CurrentTutorial

Cette solution est idéale lorsque vous devez communiquer entre une page et un UserControl.

Posted: mardi 23 octobre 2007 13:43 par cyril
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

Promesses a dit :

Quand tu dis que tu préfères travailler avec un Framework, cela veut dire que tout ce qui concerne la partie logique et accès aux données de ton site, tu le mets dans ce "framework" ?

C'est ce que tu fais a chaque fois ?

(tu as changé de photo, et euh, je vois mieux à quoi tu ressembles :) )

# octobre 23, 2007 14:54

cyril a dit :

J'aimerais écrire sur l'architecture type d'un site web... Mais je ne suis encore pas fixé au niveau de l'accés aux données, j'ai déjà utilisé BEAUCOUP de solution et rarement la même chose ou sinon c'est trop spécifique et faudrais que je donne du code que je ne peux pas donner.

Mais dans tous les cas je créer une dll pour tous ce qui est accés donnnées / logique métier (ca m'arrive aussi de séparer en plusieurs dll). Le site web ne "fait rien" il ne fait que de l'affichage tous le reste est géré dans la dll.

Généralement les principaux namespaces sont :

ProjectName.Web

ProjectName.Web.Management

ProjectName.Web.Security

ProjectName.Web.Handlers

ProjectName.Web.Modules

ProjectName.Web.UI

ProjectName.Web.UI.WebControls (je fais beaucoup de webcontrol)

ProjectName.Data

ProjectName.Tools

Le plus compliqué c'est le namespace Data, car c'est bien souvent spécifique à l'entreprise pour lequel on travaille, au chef de projet, etc... :p

Le dossier App_code ne sert qu'a mettre le code-behind des WebService :p

# octobre 23, 2007 15:52

Promesses a dit :

Merci pour ces réponses.

Je serais vraiment friand de la manière dont tu conçois le développement d'un site Web.

Pour me former, je me suis beaucoup appuyé sur http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=420

Mais comment fais tu si tu as besoin de variable d'application ou de session ?

Tout ton code s'opère toujours grâce à ta DLL ??

# octobre 23, 2007 17:36

cyril a dit :

Ca dépend si j'ai besoin de la variable session/application seulement pour la page où je me trouve ou si c'est de n'importe où.

si c'est seulement pour la page alors j'aurais une propriété dans la page. Si c'est de n'importe où j'aurais une méthode GetTrucFromSession(id) qui ira chercher dans la variable session.

Au niveau de la convention pour la clé j'utiliserais Session[String.Format("{0}#Truc@ID={0}" + typeof(ActualClass).FullName, ID)] ou un truc dans le genre (ca dépend de mon humeur :D) mais j'aurais toujours l'ID de l'élément, le nom de l'élément et le nom du type dans la clé ! Et surtout je lis et j'écris la variable session dans la même classe et si possible dans 2 méthodes côte à côte.

Je vais essayer de lire l'article que tu m'as donné tout à l'heure

# octobre 23, 2007 17:59

Promesses a dit :

Je serais déjà pas mal intéressé dans ce que tu mets (meme si ce n'est pas exhaustif) dans chacune de ces parties

# octobre 23, 2007 22:37

davidrei a dit :

Bonsoir Cyril. En ce qui me concerne, j'ai souvent utilisé un singleton Context, dans lequel je renseigne mes accesseurs. C'est un peu plus propre que la session à mon gout, mais c'est un avis personnel. Ex : Context.Current.UserID etc ..

# octobre 24, 2007 20:10

Alexandre Marlot a dit :

@Promess : J'ai lu les articles sur les architectures N-Tiers avec beaucoup d'attention et je le trouve excellent, il rejoint ce qu'avait présenté Thomas Lebrun dans son introduction sur le développement par couches. (Je te recommande d'ailleur cette article).

@davidrei : J'utilise également cette technique lorsque j'ai besoin d'acceder à des élèments en session. Je crée une classe SessionHelper qui contient des propriétés qui pointe vers la session. C'est bien cette technique dont tu parles ?

# octobre 25, 2007 13:53

davidrei a dit :

Oui en effet Alexandre, sur le principe c'est la même chose, à la différence près qu'à aucun moment dans la classe, je stocke dans l'objet Session. C'est simplement un objet singleton, avec des variables privées que je set et get à ma guise.

# octobre 26, 2007 00:16

smo a dit :

En général, toute la difficulté quand on écrit des sites ASP.NET, c'est de justement ne pas spécialiser la page. Donc présumer que Page ne sera jamais plus que System.Web.UI.Page. Cela permet de s'intégrer dans tout site web, tout framework (SharePoint, WebParts, Autres CMS, etc...), et cela signifie donc qu'il faut écrire plutôt la logique UI (je ne parle pas de logique métier pour laquelle on est d'accord, il vaut mieux qu'elle soit dans une assembly séparée) uniquement à base de contrôles ASP.NET (Control, WebControl, UserControl, TemplateControl). Et entre ces contrôles, les secrets pour conserver ses cheveux (!) face au fameux cycle de vie ASP.NET, c'est 1) d'utiliser des évènements, sans se vérouiller sur un moment de la vie de ces contrôles, et 2) de réutiliser les contrôles existants.

On peut notamment s'inspirer fortement du coupe DataBoundControl - DataSourceControl qui sont conçus spécifiquement pour se parler, sans passer par un quelconque "contrôleur" genre au hasard, ... la Page. La déclinaison la plus connue de ce couple c'est tous les contrôles ObjectDataSource, SqlDataSource, XmlDataSource, et leurs copains FormView, GridView, DetailView, etc... On peut tout à faire écrire ses propre DataSource et ses propres DataBound. L'avantage, c'est qu'on peut ensuite se brancher sur d'autres contrôles conçus de la même manière.

# octobre 26, 2007 20:46

cyril a dit :

@davidrei : Si tu créer un singleton, il est global à l'application et non à l'utilisateur. En fait tout dépend de ce qu'on veut stocker. Si c'est une variable seulement pour la durée de la requête alors ce sera on peut passer par Page.Items pour un user par les sessions et pour toute l'appli via un singleton et des propriétés statics où encore mieux via l'objet Cache. Après on peut implémenter ca de différentes façons, si on accède à l'objet dans plusieurs pages on peut utiliser un helper/singleton (j'aime bien le helper) où via une interface, si on l'utilise seulement dans une page alors via une propriété.

@smo : Pour communiquer le couple DataBoundControl - DataSourceControl utilise un container : l'arbre de collection (dont la racine est la page).

En effet pour associer un datasource à un databoundcontrol on utilise la propriété DataSourceID. Comment crois tu que le DataBoundControl récupère le datasource ? Il faut une recherche via FindControl qui utilise l'arbre de contrôle...

# octobre 27, 2007 15:19

davidrei a dit :

Oui Cyril, tu as bien décris toutes les possibilités mais, dans le cadre d'application que j'ai réalisé, le singleton était instancier par contexte utilisateur et non globale à l'application. Autrement on aurait eu des soucis avec les UserID de l'utilisateur "contexté" :p

# octobre 29, 2007 21:48

cyril a dit :

euh : singleton c'est une instance par application ? c'est un peu le but ...

# octobre 29, 2007 22:30

davidrei a dit :

Oui, c'est le but :)

Je travaillais en environnement Sharepoint, donc mon singleton interrogeait le SPContext. J'avais pas besoin de session, c'est Sharepoint qui fait sa sauce avec cette notion :p

# octobre 30, 2007 17:30

gauthier a dit :

Petite remarque au passage: utiliser la session dans ce cas est vraiment pas la chose à faire, le dictionnaire de session on le rempli souvent, mais on le vide rarement. Dans une application avec beaucoup d'utilisateur, le serveur d'application fini par tomber.

EVIL:

Session["a_magic_constant_you_type_again_and_again"]

BETTER:

static class SomethingSharedDuringASingleHttpRequest {

 IMyType MyMember {

   get {

     return static_cast

<IMyType>(HttpContext["a_magic_constant_you_type_twice"]);

   }

   set { HttpContext["a_magic_constant_you_type_twice"] = value; }

}

J'espère que le format du commentaire ne le rendra pas illisible :)

# décembre 10, 2007 02:11

cyril a dit :

Je suis tout à fait d'accord avec ce que tu dis, c'est pour ça que j'ai dit qu'on pouvait aussi utiliser Page.Items (ou HttpContext.Items) mais c'est vrai que j'aurais du le mettre plus en évidence.

# décembre 10, 2007 02:19

Promesses a dit :

Cyril, je reviens sur ce post.

Je suis actuellement confronté à un problème.

J'ai une page, deux WebUserControls.

Sur le premier WebUserControl, j'ai un gridview sur lequel je "raise" un evenement sur clique d'une ligne gridview pour récupérer l'id.

Sur ma page, sur l'évenement de mon premier webusercontrol, je souhaite faire passer l'id au deuxieme webusercontrol.

Le deuxieme webusercontrol recoit donc l'id et m'instancie un objet.

Pour tester que cela fonctionne, j'ai une textbox simple sur le deuxieme webusercontrol dans lequel je veux charger un info venant de mon objet instancié (me.textbox.text = monObjet.nom).

Et bien sur, cela ne fonctionne pas.

Ce qui que je ne comprends pas, c'est que si je suis en mode débogage, pas a pas, tout mes éléments sembent être correct. Evenement bien lancé, id bien passé, objet bien instancié, mais textbox n'affiche pas ma valeur.

Je n'arrive vraiment pas à comprendre d'ou cela peut venir.

Passer par les solutions que tu proposes est donc vraiment nécessaire ?

# janvier 25, 2008 00:51

Promesses a dit :

Aussi, est ce qu'il serait possible que tu m'indiques brievement ce que l'on trouve dans les différents namespace que tu écris plus haut ?

# janvier 25, 2008 10:08

Promesses a dit :

Encore moi,

en fait, une info en plus.

Mon premier webUserControl était dans un updatePanel et pas l'autre.

Je l'ai retiré de l'updatePanel, et la ca fonctionne sans probleme.

Alors, j'ai mis les deux dans un updatepanel.

Sur l'evenement récupéré sur la page Default, je fais un update du deuxieme updatepanl, et la ca fonctionne.

Je ne comprends pas vraiment le pourquoi du comment.

Pour aider à la compréhension, est ce que mon evenement doit être "register" ?

Parce que j'ai du mettre "EnableEventValidation" à false pour que mon click fonctionne.

# janvier 25, 2008 11:43
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01