簡體   English   中英

用戶控件事件處理程序在回發時丟失

[英]user control event handler lost on postback

我有一個名為 LeftMenu 的菜單用戶控件,它有一個鏈接項的項目符號列表。 它在 ascx 頁面上是這樣的:

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

我在if(!isPostBack)下對 page_load 中的列表進行數據綁定

我在加載控件的頁面上遇到問題。 當頁面第一次加載時,事件處理程序會觸發。 但是,當頁面回發時它不再觸發並且在 IE8 中,當我調試時,我在 Visual Studio 中收到“Microsoft JScript 運行時錯誤:預期對象”,指向“__doPostBack('LeftMenu$PublisherList','0') .” 在 FF 中,我沒有收到錯誤消息,但沒有任何反應。 沒有動態加載控件,它使用以下命令加載到 aspx 頁面上:

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

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

關於我在哪里丟失事件處理程序的任何想法?

我剛剛意識到這也發生在我擁有的另一個用戶控件上。 一個文本框和一個按鈕,我使用默認按鈕來確保按下回車鍵使用該按鈕。 .Net 將 html 中的內容轉換為:

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

所以只要我在框中輸入一個鍵,我就會在“預期對象”行中收到一個 javascript 錯誤。 這兩個問題似乎是相關的。

再次編輯:我想我需要澄清一下。 並不是我點擊了菜單項並且在回發時找不到所選項目。 我有這個帶有左側導航的搜索頁面,然后頁面的主要內容是導致回發的內容。 這個回發一切都很好。 一旦該頁面被回發,現在如果我點擊左側導航中的項目符號列表,我會收到一個 javascript 錯誤並且它失敗了。 從不調用 LeftMenu 控件的 page_init。

聽起來您可能會失去點擊,因為您沒有在 PostBack 上對列表進行數據綁定。 因此,回發試圖引用不存在的控件(特定項目符號列表項)。

您應該嘗試在 PostBack 上再次綁定列表,看看是否能解決您的問題。 但是,真正應該發生的是 LeftMenu 和 BulletedList 應該將它們的信息存儲到 ViewState 中,以便您可以確保在用戶初始頁面加載時顯示給用戶的數據與 PostBack 正在處理和使用的數據相同.

如果您為 UserControl 和其中的所有控件設置了 EnableViewState=true,則一切正常。 啟用 ViewState 后,ASP 將在 Init 觸發后從 ViewState 重新填充您的控件。 這意味着回發事件 arg(指向控件列表中的索引)仍將在該列表位置找到控件。 否則,回發時列表為空。

然而,ViewState 是魔鬼的傑作,它的設計只是為了營造一種你在一個有狀態的環境中工作的錯覺。 將它用於少量數據是可以的,但通常不建議用於模板化控件(如轉發器和列表),因為您不知道將在 ViewState 中創建多少數據。

如果您正在處理靜態或相對靜態的數據,請將其存儲在應用程序緩存中並每次都在 Page.Init 中重新綁定您的列表(請注意,它必須在 Init 中,因為 post-init 是 ASP 從 ViewState 重新綁定時;如果您首先進入那里,您的數據將被使用)。

如果您正在處理易失性數據,則會遇到問題,因為您重新綁定的數據必須與原始頁面請求完全相同,否則回發事件將針對錯誤的行觸發。 在這種情況下,您需要將初始數據存儲在 Session 中,或者您只需存儲行 id 列表(在隱藏變量或 Session 中),然后每次都從 id 重新創建要綁定的數據。

更好的解決方案是根本不使用回發事件。 嘗試將所有事件轉換為在查詢字符串上具有 ID 的 GET。 您仍然可以在第一次通過頁面時使用綁定來創建列表(正如您目前所做的那樣),您甚至可以使用新 ID 獲取同一頁面。

如果您需要在同一頁面上保持狀態但需要響應用戶更改單選按鈕選擇(或其他內容),請考慮使用 Ajax 調用來更新屏幕。 您還可以使用傳遞給 Ajax 調用的 ID 來執行此操作。

一般來說,您越遠離有狀態的 ASP,您的頁面就會變得越輕、響應速度越快。 如有必要,您還可以更好地轉向無狀態 MVC。 由於 ViewState 在您需要時不可用,因此您還可以節省大量時間用於調試晦澀難懂的問題。

我讀過的對 ViewState 的最佳分析在下面的鏈接中。 如果您完全了解它的工作原理,則可以繼續使用它,而不必承擔任何費用。

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

這可能與 javascript 相關,並且頁面中較早加載的腳本引發錯誤並導致頁面無法正確加載。

您的用戶控件是否將任何 javascript 加載到頁面上? 您能在頁面初始加載時檢查 javascript 錯誤嗎?

我將代碼移動到我們現有的項目中,出於某種奇怪的原因,我不再收到 javascript 錯誤,而是得到:

"無效的回發或回調參數。使用配置中的<pages enableEventValidation="true"/><%@ Page EnableEventValidation="true" %>啟用事件驗證。

出於安全目的,此功能驗證回發或回調事件的參數是否源自最初呈現它們的服務器控件。 如果數據有效且符合預期,請使用ClientScriptManager.RegisterForEventValidation方法來注冊回發或回調數據以進行驗證。”

我還沒有完全弄清楚我應該在哪里放置帶有用戶控件的注冊事件驗證,但同時我只是設置了enableeventvalidation=false並且它現在似乎可以工作。

看起來 doPostBack 函數丟失了,因為它的參數是文字,所以它們不可能是原因。 那是您自己的函數之一還是您的意思是調用 ASP __doPostBack 函數?

查看 Firefox 錯誤控制台或允許在 IE 中進行腳本調試,並准確查看找不到哪些對象。 更好的是,下載 Firebug 並調試它。

我有一個類似的問題。 結果證明 Akamai 正在修改用戶代理字符串,因為正在應用不需要的設置。

這意味着某些 .NET 控件沒有正確呈現 __doPostBack 代碼。 這個問題一直熱議在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM