繁体   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