2009-08-11 7 views
4

Ich habe ein Menü usercontrol namens LeftMenu, die eine Aufzählung von linkitems hat. Es ist auf der ascx Seite als solche:Benutzersteuerung Ereignishandler bei Postback verloren

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

ich die Liste in der page_load unter if(!isPostBack) Databind

ich auf einer Seite ein Problem habe, das die Steuerung lädt. Wenn die Seite zum ersten Mal geladen wird, wird der Ereignishandler ausgelöst. Wenn die Seite jedoch zurücksetzt, wird sie nicht mehr ausgelöst, und in IE8 wird beim Debuggen "Microsoft JScript-Laufzeitfehler: Objekt erwartet" in Visual Studio auf "__doPostBack ('LeftMenu $ PublisherList', '0') . " In FF bekomme ich den Fehler nicht, aber nichts passiert. Ich nicht Laden der Steuerung dynamisch, es auf der Aspx-Seite geladen wird mit:

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

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

Irgendwelche Ideen, wo ich den Event-Handler bin zu verlieren?

Ich habe gerade festgestellt, dass dies auf einer anderen Benutzersteuerung geschieht, die ich auch habe. Ein Textfeld und eine Schaltfläche und ich verwende die Standardschaltfläche, um sicherzustellen, dass die Eingabetaste gedrückt wird, um diese Schaltfläche zu verwenden. .Net wandelt diese in der html:

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

so, sobald ich einen Schlüssel in das Feld eingeben ich ein Javascript-Fehler auf der Linie erhalten sagen „Objekt erwartet.“ Es scheint, als ob die beiden Probleme miteinander zusammenhängen.

Nochmal bearbeiten: Ich denke, ich muss klären. Es ist nicht so, dass ich auf den Menüeintrag klicke und das ausgewählte Element beim Postback nicht finden kann. Ich habe diese Suchseite mit der linken Navigation darauf und dann ist der Hauptinhalt der Seite etwas, das ein Postback verursacht. Mit diesem Postback ist alles in Ordnung. Sobald diese Seite zurückgeschickt wurde, bekomme ich jetzt, wenn ich auf die Aufzählungsliste in der linken Navigationsleiste klicke, einen Javascriptfehler und es schlägt fehl. Die page_init für das LeftMenu-Steuerelement wird nie aufgerufen.

Antwort

0

Es klingt, als ob Sie den Klick verlieren könnten, weil Sie die Liste nicht auf PostBack binden. Daher versucht der Post-Back, auf ein Steuerelement (ein bestimmtes Listenelement mit Aufzählungszeichen) zu verweisen, das nicht vorhanden ist.

Sie sollten versuchen, die Liste erneut auf PostBack zu binden, nur um zu sehen, ob das Ihr Problem behebt. ABER was wirklich passieren sollte ist, dass das LeftMenu und die BulletedList ihre Informationen in ViewState speichern sollten, damit Sie sicherstellen können, dass die Daten, die dem Benutzer beim ersten Laden der Seite angezeigt wurden, dieselben Daten sind, die das PostBack verarbeitet und bearbeitet .

+0

Was ist, wenn das Menü und die Liste 100 oder 1000 Elemente enthalten? Sollten sie noch im View-Zustand gespeichert sein? – Phaedrus

+0

Im Idealfall stirbt ViewState einen schrecklichen Tod und kommt nie wieder zurück, so dass diese Mysterien der PostBacks nie ihre hässlichen Köpfe aufstellen und unsere Seiten leicht und luftig bleiben ;-) Das ist gesagt, das ist ein linkes Navigationsmenü auf einer Website, also bezweifle ich, dass es mehr als ein paar Sachen gibt. Offensichtlich, wenn dies eine Art von Datenbankaufruf wäre, würden Sie es zwischenspeichern und das könnte dazu beitragen, den Seitenaufruf hell zu halten und ViewState nicht zu benötigen, aber Sie können nicht garantieren, dass die Liste, an der der PostBack arbeitet, dieselbe ist als das Original, das der Benutzer gesehen hat (wenn der Cache abläuft). –

+0

Das Entfernen von if (! IsPostBack) {...} hilft nicht. Die Daten werden sich kaum ändern, sollte ich sie noch im Viewstate speichern? –

0

Wenn Sie EnableViewState = true für Ihr Benutzersteuerelement und alle Steuerelemente darin haben, sollte alles gut funktionieren. Wenn ViewState aktiviert ist, wird ASP Ihre Steuerelemente von ViewState neu initialisieren, nachdem Init ausgelöst wurde. Dies bedeutet, dass das Postback-Ereignis arg (das auf einen Index in Ihrer Kontrollliste zeigt) immer noch das Steuerelement an dieser Listenposition findet. Ansonsten ist die Liste beim Postback leer.

ViewState ist jedoch das Werk des Teufels und wurde entworfen, um die Illusion zu fördern, dass Sie in einer Stateful-Umgebung arbeiten. Es ist in Ordnung, es für kleine Datenmengen zu verwenden, aber normalerweise nicht für Vorlagensteuerelemente wie Repeater und Listen, da Sie keine Ahnung haben, wie viele Daten in ViewState erstellt werden.

Wenn Sie mit statischen oder relativ statischen Daten arbeiten, speichern Sie diese im Anwendungscache und binden Sie Ihre Listen jedes Mal erneut in Page.Init ein (beachten Sie, dass es in Init sein muss, da das Post-Init-Verfahren der ASP ist) ViewState; wenn Sie zuerst dort ankommen, werden Ihre Daten stattdessen verwendet).

Wenn Sie mit flüchtigen Daten zu tun haben, haben Sie ein Problem, weil die Daten, die Sie binden, genau mit der ursprünglichen Seitenanforderung übereinstimmen müssen, da andernfalls die Postback-Ereignisse mit den falschen Zeilen ausgelöst werden. In diesem Fall müssen Sie entweder Ihre anfänglichen Daten in der Sitzung speichern oder Sie speichern einfach die Liste der Zeilen-IDs (in einer versteckten Variablen oder Sitzung) und Sie erstellen die Daten neu, an die jedes Mal von den IDs gebunden wird.

Eine noch bessere Lösung ist, Postback-Ereignisse überhaupt nicht zu verwenden. Versuchen Sie, alle Ihre Ereignisse in GETs umzuwandeln, die eine ID in der Abfragezeichenfolge haben. Sie können die Liste weiterhin erstellen, indem Sie das erste Mal über die Seite binden (wie Sie es gerade tun), und Sie können sogar dieselbe Seite mit einer neuen ID abrufen.

Wenn Sie den Status auf derselben Seite beibehalten müssen, aber dem Benutzer antworten müssen, wenn er eine Optionsfeldauswahl (oder etwas anderes) ändert, sollten Sie Ajax-Aufrufe verwenden, um den Bildschirm zu aktualisieren. Sie tun das auch mit einer ID, die Sie an den Ajax-Aufruf übergeben.

Im Allgemeinen, je mehr Sie von der Verwendung von Stateful ASP, desto leichter und reaktionsfähiger werden Ihre Seiten werden. Sie werden auch in einer besseren Position sein, um bei Bedarf zu staatenlosen MVC zu wechseln. Sie sparen viel Zeit beim Debuggen obskurer Probleme, da ViewState nicht verfügbar ist, wenn Sie es benötigen.

Die beste Analyse von ViewState, die ich gelesen habe, ist im folgenden Link. Wenn Sie vollständig verstanden haben, wie es funktioniert, können Sie es weiterhin nutzen, ohne dass die Kosten dafür anfallen.

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

+0

Tut mir leid, ich glaube, ich habe mich nicht gut genug erklärt. Es ist nicht so, dass ich das ausgewählte Element auf dem Postback nicht finden kann, das die meiste Zeit funktioniert. Das Problem ist, wenn ich dieses Steuerelement auf einer Seite habe, die zu sich selbst zurückschickt und dann versucht, auf ein Element in der Liste zu klicken. Ich erhalte einen JavaScript-Fehler "Object Expected" und es funktioniert einfach nicht –

0

Es ist möglich, dass dieser Javascript in Zusammenhang stehen könnte, und dass ein Skript, das früher in der Seite wird geladen wird einen Fehler werfen und verursachte die Seite nicht richtig geladen werden.

Sind Ihre Benutzersteuerungen, die irgendein Javascript auf der Seite laden? Können Sie beim ersten Laden der Seite nach JavaScript-Fehlern suchen?

0

ich den Code in ein bestehendes Projekt zogen wir und aus irgendeinem seltsamen Grund haben, hielt ich die JavaScript-Fehler bekommen und stattdessen bekam.

„Invalid Postback oder Callback-Argument Ereignisvalidierung mit <pages enableEventValidation="true"/> in der Konfiguration aktiviert ist oder <%@ Page EnableEventValidation="true" %> auf einer Seite.

aus Sicherheitsgründen überprüft dieses Feature, dass Argumente für Postback oder die vom Server Control-Ereignisse Rückruf stammen, die ursprünglich sie gemacht wird. Wenn die Daten gültig und erwartet, verwenden sie die ClientScriptManager.RegisterForEventValidation Methode, um zu registrieren Postback- oder Callback-Daten für die Validierung. "

Ich habe nicht ganz herausgefunden, wo ich die Registrierung Ereignis Validierung mit einem Benutzer Steuerelement setzen sollte, aber in der Zwischenzeit habe ich nur enableeventvalidation=false gesetzt und es scheint jetzt zu arbeiten.

+0

Führen Sie dies auf Ihrem lokalen Computer oder auf einem Dev/Test-Cluster von Maschinen? Es kann sein, dass beim Springen von Maschinen die Maschinenschlüssel nicht richtig aufeinander abgestimmt sind. Wenn Sie dies lokal auf Ihrem Rechner treffen, dann vergessen Sie :-) –

0

Es scheint, dass die Funktion doPostBack fehlt, da ihre Argumente Literale sind, so dass sie nicht die Ursache sein können. Ist das eine Ihrer eigenen Funktionen oder wollten Sie die ASP __doPostBack-Funktion aufrufen?

Werfen Sie einen Blick auf die Firefox-Fehlerkonsole oder erlauben Sie das Debuggen von Skripten im IE und sehen Sie genau, welches Objekt nicht gefunden werden kann. Noch besser, laden Sie Firebug herunter und debuggen Sie es.

0

Ich hatte ein ähnliches Problem. Es stellte sich heraus, dass Akamai die User-Agent-Zeichenfolge änderte, weil eine Einstellung angewendet wurde, die nicht benötigt wurde.

Das bedeutete, dass einige .NET-Steuerelemente den Code von __doPostBack nicht ordnungsgemäß rendern. Dieses Problem wurde mit here gebloggt.