我正在尝试使用AJAX工具包的UpdatePanel
创建动态UI。
让我解释一下我的应用程序的上下文。有许多个人资料。每个配置文件都有许多产品类。每个产品类都有许多产品。 我正在实施产品的比较。
个人资料由RadioButtonList
表示(动态创建)。对于所选配置文件的每个产品类,DropDownList
需要
动态创建,允许用户选择该类的产品。
第一次选择时一切正常。但是,当我尝试选择其他产品并单击第二次提交时,将引发以下错误:
Microsoft JScript运行时错误: Sys.WebForms.PageRequestManagerServerErrorException:无效的回发 或回调参数。使用配置或<%@ Page启用事件验证 EnableEventValidation =“true”%>在页面中。
有关为什么抛出此错误的任何提示都会非常有用。
protected void Page_Load(object sender, EventArgs e)
{
pnlDynamic.Visible = false;
if (!this.IsPostBack)
{
LoadProfiles(); //Data binding is done for radio button list
}
else
{
btnSubmit.Enabled = true;
GenerateProductUI(ProfileID); //DropDownLists are dynamically created and populated from database
//ProfileID is the selected profile id
}
}
<asp:UpdatePanel runat="server" id="UpdatePanel" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="rblProfiles" eventname="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<asp:Panel ID="Panel1" runat="server">
<asp:RadioButtonList ID="rblProfiles" runat="server" AutoPostBack="True"
onselectedindexchanged="rblProfiles_SelectedIndexChanged">
</asp:RadioButtonList>
</asp:Panel>
<br />
<asp:Panel ID="pnlDynamic" runat="server" Visible="false">
<asp:Panel ID="Panel2" runat="server">
<asp:Table ID="table" runat="server"/> <!-- Product dropdowns generated in table -->
</asp:Panel>
</asp:Panel>
<br />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" CssClass="btnSubmit" AutoPostBack="True" />
<asp:UpdatePanel runat="server" id="UpdatePanel1" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="btnSubmit" eventname="Click" />
</Triggers>
<ContentTemplate>
<asp:Panel ID="pnlResult" runat="server" Visible="false">
<!--Result displayed-->
</asp:Panel>
<br />
</ContentTemplate>
</asp:UpdatePanel>
答案 0 :(得分:1)
重要!每个人都不会理解事件的确认应该理解他什么是禁用的!
想象一下,您有一个博客应用程序(或银行应用程序),并且有一个评论(或银行帐户)列表,所有用户都可以看到评论(或帐户),但只有版主(或经理)可以删除它们。因此,您可以根据用户的访问权限编写检查以切换删除按钮的可见属性。非主持人(经理)的用户无法删除评论(帐户)。问题解决了。
但是,如果您禁用事件验证,恶意用户可以发送声称已按下删除按钮的帖子请求,尽管它从未为他启用过。通常情况下,事件验证会启动并产生异常但是如果它被禁用,ASP.NET将不会检查按钮是否可见,并且只运行按钮单击处理程序代码并且注释(帐户)将被删除。如果您检查用户是否可以在按钮单击事件中删除,但是您还应该考虑另一个开发人员可以稍后再添加另一个按钮(编辑?)而不会注意到事件验证已被禁用,则可以防止这种情况。此外,页面上的所有其他按钮都需要进行适当的检查。如果禁用事件验证,请务必小心!
发生错误是因为您正在触发从呈现原始页面时不存在的控件的回发。修复它的一种方法是禁用此页面的事件验证,但是您应该确保检查请求事件本身更改的用户的凭据,否则这是一个安全问题,因为用户将能够“按下”根本没有渲染的按钮(例如,他无权访问的产品)。
您可以通过页面指令禁用事件验证:
<%@ Page EnableEventValidation="false" ... %>
我相信也可以将更新面板的更新模式设置为始终而不是条件,这可能会解决问题(您可以尝试并告诉我们吗?)但这会增加通过网络发送的数据。如果这是一个很好的权衡取决于你的用例,你在页面上的更新面板的数量和大小(你越多越糟糕)。如果它是一个内部应用程序或者这个UI被访问的比较少,我会采用这种方法(假设它有效,因为我没有验证)。
BTW这实际上不是脚本错误。您收到客户端脚本错误只是因为错误通过AJAX请求浮出水面。这纯粹是由于您的代码存在潜在安全问题而引发的服务器错误。
答案 1 :(得分:1)
在页面顶部添加<%@ Page EnableEventValidation="false" %>
。
答案 2 :(得分:1)
创建动态下拉列表后,您必须在每个页面init或页面加载上重新创建它们或任何动态创建的控件。在这种情况下,您不需要使用EnableEventValidation="false"
。
protected void Page_Load(object sender, EventArgs e)
{
pnlDynamic.Visible = false;
if (!this.IsPostBack)
{
LoadProfiles(); //Data binding is done for radio button list
}
else
{
btnSubmit.Enabled = true;
}
GenerateProductUI(ProfileID); //DropDownLists are dynamically created and populated from database
//ProfileID is the selected profile id
}
或者只是将GenerateProductUI(ProfileID)
从Page_Load
移到Page_Init