asp.net 回发时丢失用户控件事件处理程序

e7arh2l6  于 2023-01-06  发布在  .NET
关注(0)|答案(6)|浏览(151)

我有一个名为LeftMenu的菜单用户控件,它有一个链接项的项目符号列表,它在ascx页面上的位置如下:

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

我将列表数据绑定到page_load中的if(!isPostBack)
加载控件的页面出现问题。当页面首次加载时,事件处理程序触发。但是,当页面回发时,它不再触发,并且在IE8中进行调试时,我收到“Microsoft JScript运行时错误:在Visual Studio中需要对象””,指向“__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错误,它失败了。2 LeftMenu控件的page_init从来没有被调用过。

ar5n3qh5

ar5n3qh51#

这可能与javascript有关,页面中较早加载的脚本引发错误,导致页面无法正确加载。
你的用户控件是否加载了javascript到页面上?你能检查一下页面初始加载时的javascript错误吗?

icomxhvb

icomxhvb2#

我将代码移到了我们现有的项目中,出于某种奇怪的原因,我停止了JavaScript错误,而是得到:
“无效的回发或回调参数。事件验证是使用配置中的<pages enableEventValidation="true"/>或页面中的<%@ Page EnableEventValidation="true" %>启用的。
出于安全目的,此功能验证回发或回调事件的参数是否源自最初呈现这些事件的服务器控件。如果数据有效且符合预期,请使用ClientScriptManager.RegisterForEventValidation方法注册回发或回调数据以进行验证。
我还没有完全弄清楚我应该把注册事件验证和用户控件放在哪里,但同时我刚刚设置了enableeventvalidation=false,现在它似乎可以工作了。

hc8w905p

hc8w905p3#

似乎缺少doPostBack函数,因为它的参数是文本,因此不可能是原因。这是您自己的函数之一,还是您打算调用ASP __doPostBack函数?
看看Firefox的错误控制台,或者在IE中允许脚本调试,看看到底是什么对象找不到。更好的是,下载Firebug并调试它。

k4emjkb1

k4emjkb14#

我也遇到过类似的问题,原来Akamai修改用户代理字符串是因为应用了一个不需要的设置。
这意味着一些.NET控件没有正确呈现__doPostBack代码。此问题已在here上发表。

apeeds0o

apeeds0o5#

听起来您可能会失去点击的机会,因为您没有对PostBack上的列表进行DataBinding。因此,Postback尝试引用不存在的控件(特定的项目符号列表项)。
您应该尝试在PostBack上再次绑定列表,看看这是否解决了您的问题。但是,真正应该发生的是,LeftMenu和BulletedList应该将它们的信息存储到ViewState中,以便您可以确保在用户初始页面加载时显示给用户的数据与PostBack正在处理和使用的数据相同。

nuypyhwy

nuypyhwy6#

如果UserControl及其所有控件的EnableViewState=true,则一切都应正常。启用ViewState后,ASP将在Init激发后从ViewState重新膨胀控件。这意味着回发事件arg(指向控件列表中的索引)仍将在该列表位置找到控件。否则,回发时列表为空。
然而,ViewState是魔鬼的杰作,它的设计只是为了制造一种错觉,让人以为你在一个有状态的环境中工作。可以将它用于少量的数据,但通常不建议将它用于模板控件,如repeater和list,因为你不知道在ViewState中会创建多少数据。
如果您正在处理静态或相对静态的数据,请将其存储在应用程序缓存中,并在Page.Init中重新绑定您的列表(请注意,它必须在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

相关问题