IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ASP.NET Discussion :

[ASP.NET 2.0] IPostBackEventHandler & RaisePostBackEvent non appelé


Sujet :

ASP.NET

  1. #1
    Membre confirmé Avatar de NeoMan
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 171
    Par défaut [ASP.NET 2.0] IPostBackEventHandler & RaisePostBackEvent non appelé
    Bonjour à tous !

    Je pensais m'engager dans un développement rapide, mais un unique point me bloque depuis hier soir...
    J'ai décidé de faire un contrôle jouant le rôle de Button, ImageButton et LinkButton; avec une propriété Format permettant de savoir quel type de bouton on veut. Mon contrôle implémente donc IButtonControl et IPostBackEventHandler.
    Le problème c'est que dans certaines situations les évènements du contrôle ne sont pas traité (la procédure RaisePostBackEvent n'est pas appelé) !

    Voici un résumé du code source :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public class GenericButton : WebControl, IButtonControl, IPostBackEventHandler
    {
        public event EventHandler Click;
     
        [...]
     
        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            if (Page != null)
                Page.VerifyRenderingInServerForm(this);
     
            PostBackOptions postBackOptions = GetPostBackOptions();
     
            if ((UniqueID != null) && ((postBackOptions == null) || (postBackOptions.TargetControl == this)))
                writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID);
     
            writer.AddAttribute(HtmlTextWriterAttribute.Onclick, Page.ClientScript.GetPostBackEventReference(postBackOptions, true));
     
            [...]
     
            base.AddAttributesToRender(writer);
        }
     
        protected virtual PostBackOptions GetPostBackOptions()
        {
            PostBackOptions options = new PostBackOptions(this, String.Empty);
            if (!String.IsNullOrEmpty(PostBackUrl))
                options.ActionUrl = HttpUtility.UrlPathEncode(ResolveClientUrl(PostBackUrl));
     
            if ((CausesValidation && (Page != null)) && (Page.GetValidators(ValidationGroup).Count > 0))
            {
                options.PerformValidation = true;
                options.ValidationGroup = ValidationGroup;
            }
     
            options.ClientSubmit = !UseSubmitBehavior;
     
            return options;
        }
     
        protected virtual void OnClick(EventArgs e)
        {
            if (Click != null)
                Click(this, e);
        }
     
        [...]
     
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
     
            if (Page != null)
                Page.RegisterRequiresRaiseEvent(this);
        }
     
        public void RaisePostBackEvent(string eventArgument)
        {
            if (Page != null)
                Page.ClientScript.ValidateEvent(UniqueID, eventArgument);
     
            [...]
     
            OnClick(EventArgs.Empty);
     
            [...]
        }
     
        [...] 
    }
    Le problème a été détecté dans le cas d'utilisation suivant :
    - Mise en place du contrôle dans un Repeater dans un UserControl.

    Dans certains projets je n'ai aucun problème. Et je n'arrive pas à déterminé ce qui peut poser problème. Vous avez des idées ??

    Merci d'avance

    @++

    NeoMan

  2. #2
    Membre confirmé Avatar de NeoMan
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 171
    Par défaut
    Je m'en doutait mais ça vient d'être confirmer; dans les cas où l'évènement n'est pas traité c'est que le composant cible (celui qui est censé traité l'évènement) n'existe pas encore lorsque la page est dans son RaisePostBackEvent.

    En fait, après longue analyse dans Reflector;quand la page fait sa gestion d'évènement elle exécute ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    private void RaisePostBackEvent(NameValueCollection postData)
    {
        if (this._registeredControlThatRequireRaiseEvent != null)
        {
            this.RaisePostBackEvent(this._registeredControlThatRequireRaiseEvent, null);
        }
        else
        {
            string text = postData["__EVENTTARGET"];
            bool flag = !string.IsNullOrEmpty(text);
            if (flag || (this.AutoPostBackControl != null))
            {
                Control control = null;
                if (flag)
                {
                    control = this.FindControl(text);
                }
                if ((control != null) && (control.PostBackEventHandler != null))
                {
                    string eventArgument = postData["__EVENTARGUMENT"];
                    this.RaisePostBackEvent(control.PostBackEventHandler, eventArgument);
                }
            }
            else
            {
                this.Validate();
            }
        }
    }
    Elle arrive donc au moment où elle peut potentiellement faire un FindControl (ce qui est toujours le cas de mes projets). J'ai remarqué dans des les projets où le contrôle fonctionne bien, les contrôles en question ne sont pas nécessairement instanciés au moment de l'appel à Page.FindControl. Mais cet appel force l'instanciation de la sous-arborescence de contrôles nécessaire. Ce qui fait que le résultat de Page.FindControl est positif.

    Or dans les cas où le contrôle est défaillant, Page.FindControl n'instancie aucun contrôle (alors qu'il devrait); et donc sont résultat est donc négatif. Ne trouvant pas le contrôle cible devait traité l'évènement, la page continue son cycle de vie te aucun évènement n'est géré.

    Donc allons y pour une petite analyse de FindControl

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    protected virtual Control FindControl(string id, int pathOffset)
    {
        string text;
        this.EnsureChildControls();
        if (!this.flags[0x80])
        {
            Control namingContainer = this.NamingContainer;
            if (namingContainer != null)
            {
                return namingContainer.FindControl(id, pathOffset);
            }
            return null;
        }
        if (this.HasControls() && (this._occasionalFields.NamedControls == null))
        {
            this.EnsureNamedControlsTable();
        }
        if ((this._occasionalFields == null) || (this._occasionalFields.NamedControls == null))
        {
            return null;
        }
        char[] anyOf = new char[] { '$', ':' };
        int num = id.IndexOfAny(anyOf, pathOffset);
        if (num == -1)
        {
            text = id.Substring(pathOffset);
            return (this._occasionalFields.NamedControls[text] as Control);
        }
        text = id.Substring(pathOffset, num - pathOffset);
        Control control2 = this._occasionalFields.NamedControls[text] as Control;
        if (control2 == null)
        {
            return null;
        }
        return control2.FindControl(id, num + 1);
    }
    Mais là il y a trop de notion qui me dépasse et je n'arrive pas à suivre...
    Vous avez un idée de pourquoi dans certain cas un contrôle utilisé dans un contrôle à template ne serait pas instancié ??

    J'ai comme qui dirait l'impression de tourné en rond d'un mouvement circulaire...

    @++

    NeoMan

Discussions similaires

  1. Réponses: 5
    Dernier message: 19/07/2010, 16h38
  2. [ASP .NET][VB] Gestion des erreurs non gérées
    Par aloisio11 dans le forum ASP.NET
    Réponses: 7
    Dernier message: 04/10/2007, 10h13
  3. [ASP.NET] Non mise en cache d'une image
    Par Azephel dans le forum ASP.NET
    Réponses: 2
    Dernier message: 07/09/2007, 12h36
  4. DLL COM non managé <-> ASP.NET
    Par JLOUIS dans le forum C++/CLI
    Réponses: 2
    Dernier message: 20/08/2007, 10h16
  5. [ASP.NET 2.0 / C#]Cookie non conservé.
    Par maniaco_jazz dans le forum ASP.NET
    Réponses: 4
    Dernier message: 05/07/2007, 13h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo