2009-08-11 5 views
4

J'ai un menu usercontrol appelé LeftMenu qui contient une liste de liens. Il est sur la page ascx en tant que tel:Le gestionnaire d'événements de contrôle utilisateur a été perdu lors de la publication

<asp:BulletedList ID="PublisherList" DisplayMode="LinkButton" OnClick="PublisherList_Click" cssClass="Menu" runat="server"></asp:BulletedList> 

Je Databind la liste dans le page_load sous if(!isPostBack)

Je vais avoir un problème sur une page qui charge le contrôle. Lorsque la page est chargée, le gestionnaire d'événements se déclenche. Cependant, lorsque la page est postée, elle ne se déclenche plus et dans IE8, lorsque je débogue, j'obtiens "Erreur d'exécution Microsoft JScript: Objet attendu" dans Visual Studio pointant sur "__doPostBack ('LeftMenu $ PublisherList', '0') " Dans FF, je ne reçois pas l'erreur, mais rien ne se passe. Je pas charger dynamiquement le contrôle, il est chargé sur la page ASPX en utilisant:

<%@ Register TagPrefix="Standards" TagName="LeftMenu" Src="LeftMenu.ascx" %> 

<Standards:LeftMenu ID="LeftMenu" runat="server"/> 

Toutes les idées de l'endroit où je perdre le gestionnaire d'événements? Je viens juste de me rendre compte que cela se passe sur un autre contrôle utilisateur que j'ai également. Une zone de texte et un bouton et j'utilise le bouton par défaut pour m'assurer que l'appui sur la touche Entrée utilise ce bouton. .Net convertit que dans le code HTML à:

<div id="SearchBarInclude_SearchBar" onkeypress="javascript:return WebForm_FireDefaultButton(event, 'SearchBarInclude_QuickSearchButton')"> 

dès que j'entrer une clé dans la boîte, je reçois une erreur javascript sur la ligne disant « objet prévu. » Il semble que les deux problèmes sont liés. Modifier à nouveau: Je pense que j'ai besoin de clarifier. Ce n'est pas que je clique sur l'élément de menu et il ne peut pas trouver l'élément sélectionné sur la publication. J'ai cette page de recherche avec la navigation à gauche sur elle, puis le contenu principal de la page est quelque chose qui provoque une publication. Tout va bien avec cette publication. Une fois que cette page a été postée, maintenant si je clique sur la liste à puces dans la navigation de gauche, j'obtiens une erreur javascript et elle échoue. Le paramètre page_init du contrôle LeftMenu n'est jamais appelé.

Répondre

0

Il semble que vous perdiez le clic car vous n'êtes pas lié à DataBinding dans PostBack. Par conséquent, la publication tente de faire référence à un contrôle (un élément de liste à puces spécifique) qui n'existe pas.

Vous devriez essayer de lier à nouveau la liste sur PostBack juste pour voir si cela résout votre problème. MAIS, ce qui devrait vraiment arriver est que LeftMenu et BulletedList stockent leurs informations dans ViewState afin que vous puissiez vous assurer que les données qui ont été montrées à l'utilisateur lors du chargement initial de la page sont les mêmes que celles traitées par PostBack. .

+0

Que faire si le menu et la liste contiennent 100 ou 1000 éléments? Devraient-ils encore être stockés dans l'état d'affichage? – Phaedrus

+0

Idéalement, ViewState meurt d'une mort horrible et ne revient jamais pour que ces mystères de PostBacks n'éveillent jamais leurs têtes hideuses et que nos pages restent légères et aérées ;-) Ceci étant dit, il s'agit d'un menu de gauche sur un site web, donc je doute qu'il y ait plus que quelques articles. De toute évidence, si c'était une sorte d'appel de base de données, vous voudriez le mettre en cache et cela pourrait aider à garder l'appel de page léger et ne pas exiger ViewState, mais vous n'êtes pas garanti que la liste sur laquelle travaille PostBack est la même comme l'original vu par l'utilisateur (si le cache expire). –

+0

Le supprimer de if (! IsPostBack) {...} n'aide pas. Les données changent rarement, dois-je encore le stocker dans le viewstate? –

0

Si vous avez EnableViewState = true pour votre UserControl et tous les contrôles qu'il contient, tout devrait fonctionner correctement. Avec ViewState activé, ASP va regonfler vos contrôles à partir de ViewState après le lancement de Init. Cela signifie que l'argument postback (qui pointe vers un index de votre liste de contrôle) trouvera toujours le contrôle dans cette position de liste. Sinon, la liste est vide lors de la publication. Cependant, ViewState est le travail du diable et a été conçu simplement pour favoriser l'illusion que vous travaillez dans un environnement dynamique. Il est acceptable de l'utiliser pour de petites quantités de données, mais ce n'est généralement pas recommandé pour les contrôles basés sur des modèles tels que les répéteurs et les listes, car vous n'avez aucune idée de la quantité de données créées dans ViewState. Si vous traitez des données statiques ou relativement statiques, stockez-les dans le cache de l'application et reliez vos listes dans Page.Init à chaque fois (notez que cela doit être dans Init car post-init est quand ASP se reconnecte à partir de ViewState, si vous y entrez d'abord, vos données seront utilisées à la place).Si vous traitez des données volatiles, vous avez un problème car les données que vous reliez doivent être exactement identiques à la demande de page d'origine, sinon les événements de publication seront déclenchés contre les mauvaises lignes. Dans ce cas, vous devez soit stocker vos données initiales dans Session, soit stocker simplement la liste des identifiants de lignes (dans une variable cachée ou Session) et recréer à chaque fois les données à lier à partir des identifiants.

Une solution encore meilleure consiste à ne pas utiliser d'événements de publication. Essayez de transformer tous vos événements en GETs ayant un ID sur la chaîne de requête. Vous pouvez toujours créer la liste en utilisant la liaison la première fois à travers la page (comme vous le faites actuellement), et vous pouvez même obtenir la même page avec un nouvel ID.

Si vous devez conserver l'état sur la même page mais devez répondre à l'utilisateur en changeant une sélection de bouton radio (ou autre chose), pensez à utiliser les appels Ajax pour mettre à jour l'écran. Vous faites également cela avec un ID que vous passez à l'appel Ajax.

En général, plus vous utilisez d'ASP avec état, plus vos pages deviendront claires et réactives. Vous serez également dans une meilleure position pour passer à MVC sans état si nécessaire. Vous économiserez également beaucoup de temps perdu à déboguer des problèmes obscurs parce que ViewState n'est pas disponible quand vous en avez besoin.

La meilleure analyse de ViewState que j'ai lu est dans le lien ci-dessous. Si vous comprenez parfaitement comment cela fonctionne, vous pouvez continuer à l'utiliser sans nécessairement en subir les coûts.

http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/truly-understanding-viewstate.aspx

+0

Désolé, je suppose que je ne me suis pas bien expliqué. Ce n'est pas que je ne peux pas trouver l'élément sélectionné sur la publication, cela fonctionne la plupart du temps. Le problème est lorsque j'ai ce contrôle sur une page qui se reporte sur lui-même et puis essayez de cliquer sur un élément de la liste. Je reçois une erreur javascript "Objet attendu" et cela ne fonctionne tout simplement pas –

0

Il est possible que cela pourrait être lié javascript, et qu'un script qui charge plus tôt dans la page est de lancer une erreur et provoquer la page de ne pas être chargé correctement.

Vos commandes username sont-elles en train de charger un quelconque javascript sur la page? Pouvez-vous vérifier les erreurs javascript sur le chargement initial de la page?

0

je me suis déplacé le code dans un projet existant que nous avons et pour une raison étrange, je me suis arrêté d'obtenir les erreurs javascript et la place a obtenu:.

« non valide postback ou un argument rappel de validation d'événement est activé à l'aide <pages enableEventValidation="true"/> dans la configuration ou <%@ Page EnableEventValidation="true" %> dans une page.

pour des raisons de sécurité, cette fonction vérifie que les arguments à postback ou à des événements de rappel proviennent du contrôle du serveur qui les a rendu à l'origine. Si les données sont valides et attendu, utilisez la méthode ClientScriptManager.RegisterForEventValidation pour enregistrer la données de retour ou de rappel pour validation. "

Je n'ai pas encore tout à fait compris où je suis censé mettre la validation d'événement de registre avec un contrôle d'utilisateur, mais en attendant je mets juste enableeventvalidation=false et cela semble fonctionner maintenant.

+0

L'exécutez-vous sur votre ordinateur local ou sur un cluster de développement/test? Il se peut que si vous sautez des machines, les clés de la machine ne sont pas correctement configurées pour correspondre les unes aux autres. Si vous frappez cela localement sur votre machine, alors ne vous inquiétez pas :-) –

0

Il semble que la fonction doPostBack soit manquante car ses arguments sont des littéraux, donc ils ne peuvent pas en être la cause. Est-ce l'une de vos propres fonctions ou avez-vous l'intention d'appeler la fonction ASP __doPostBack?

Jetez un oeil à la console d'erreur de Firefox ou permettez le déboguage de script dans IE et voyez exactement quel objet est introuvable. Mieux encore, téléchargez Firebug et déboguez-le.

0

J'ai eu un problème similaire. Il s'est avéré qu'Akamai modifiait la chaîne user-agent car un paramètre n'était pas nécessaire.Cela signifie que certains contrôles .NET n'ont pas rendu correctement le code __doPostBack. Ce numéro a été blogué here.

Questions connexes