无效的回发或回调参数(HiddenField和容器Visible = false)

时间:2013-05-10 17:25:45

标签: c# asp.net validation postback asynchronous-postback

我找不到符合我情况的答案,所以我发布了一个已回答的问题,希望能帮到别人。

我收到了错误

  

无效的回发或回调参数。事件验证已启用   在配置中使用或<%@   Page EnableEventValidation =“true”%>在一个页面中。为了安全   目的,此功能验证回发或回调的参数   事件源自最初呈现的服务器控件   他们。如果数据有效且预期,请使用   ClientScriptManager.RegisterForEventValidation方法   注册回发或回调数据以进行验证。

   at System.Web.UI.ClientScriptManager.ValidateEvent(String uniqueId, String argument)
   at System.Web.UI.Control.ValidateEvent(String uniqueID, String eventArgument)
   at System.Web.UI.WebControls.HiddenField.LoadPostData(String postDataKey, NameValueCollection postCollection)
   at System.Web.UI.WebControls.HiddenField.System.Web.UI.IPostBackDataHandler.LoadPostData(String postDataKey, NameValueCollection postCollection)
   at System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

我有一个Databound ListView(有几百行),每行都有按钮。按钮带来一个弹出窗口。弹出窗口有下拉列表和其他控件进行异步回发。我需要确保我做异步回发以避免刷新我的大表。

当我单击一行上的按钮时出现错误,然后更改弹出窗口内的下拉列表,该列表会触发回发(所选项目已更改)。吊杆。

这是减少样本的标记,没有弹出窗口和javascript!它仍然表现出问题。单击一行按钮两次以获取错误。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestPopupAsynchPostback.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="scriptMgr" runat="server" ScriptMode="Debug" EnablePartialRendering="true"
            EnableScriptGlobalization="true" EnableScriptLocalization="true" EnablePageMethods="true"/>
        <asp:ObjectDataSource ID="ListDataSource" runat="server" SelectMethod="List" TypeName="TestPopupAsynchPostback.Default" />
        <asp:Label runat="server" ID="PageLabel"></asp:Label>
        <asp:ListView ID="EL" runat="server" DataSourceID="ListDataSource" OnItemDataBound="EntityList_OnItemDataBound">
            <LayoutTemplate>
                <table border="1">
                    <tr id="itemPlaceholder" runat="server" enableviewstate="false">
                    </tr>
                </table>
            </LayoutTemplate>
            <ItemTemplate>
                <tr runat="server" id="DefaultRow" enableviewstate="false">
                    <td>
                        <asp:Label ID="Lbl" runat="server" EnableViewState="false" />
                    </td>
                    <td>
                        <button runat="server" type="button" id="ReportingButton" enableviewstate="false" onserverclick="ReportingButton_OnClick" causesvalidation="false">click</button>
                    </td>
                </tr>
                <%-- Fix part 1: Change SpecialRow  visible = true--%>
                <tr runat="server" id="SpecialRow" visible="false" enableviewstate="false">
                    <td>
                        <asp:Label ID="Lbl2" runat="server" EnableViewState="false" />
                        <asp:HiddenField runat="server" ID="fn_hid" />
                    </td>
                </tr>
            </ItemTemplate>
        </asp:ListView>
    </form>
</body>
</html>

这是背后的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace TestPopupAsynchPostback
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            ScriptManager sm = ScriptManager.GetCurrent(Page);
            PageLabel.Text = DateTime.UtcNow.ToString() + " IsPostBack:" + IsPostBack + " IsInAsyncPostBack:" + (sm == null ? "" : sm.IsInAsyncPostBack.ToString());
        }

        protected override void Render(HtmlTextWriter writer)
        {
            ScriptManager sm = ScriptManager.GetCurrent(this.Page);
            if (sm != null)
            {
                foreach (ListViewDataItem row in EL.Items)
                {
                    HtmlButton reportingButton = row.FindControl("ReportingButton") as HtmlButton;
                    if (reportingButton != null)
                        sm.RegisterAsyncPostBackControl(reportingButton);
                }
            }
            base.Render(writer);
        }

        public IList<string> List()
        {
            return (new string[] { "ONE", "TWO"}).ToList();
        }

        protected void ReportingButton_OnClick(object sender, EventArgs e)
        {
            //Do something useful here, for now, just a postback event
        }

        protected void EntityList_OnItemDataBound(object sender, ListViewItemEventArgs e)
        {
            Label lbl = e.Item.FindControl("Lbl") as Label;
            Label lbl2 = e.Item.FindControl("Lbl2") as Label;
            lbl.Text = lbl2.Text = e.Item.DataItem.ToString();

            HtmlTableRow specialRow = e.Item.FindControl("SpecialRow") as HtmlTableRow;
            if (e.Item.DataItemIndex%2 == 0)
            {
                HiddenField fn_hid = e.Item.FindControl("fn_hid") as HiddenField;
                fn_hid.Value = "test1";
                specialRow.Visible = true;
            }
            //Fix part 2: set SpecialRow Visible = false in code behind
            //else
            //    specialRow.Visible = false;
        }
    }
}

1 个答案:

答案 0 :(得分:2)

我最初认为我的javascript是错误的,因为我正在修改它。但是,创建示例页面的过程帮助我找到了问题。

事实证明它与javascript或弹出窗口无关。它与TR HtmlControl(asp.net服务器端控件)中包含的HiddenField有关,Visible = false IN MARKUP。然后,当我需要OnItemDataBound事件时,我使用后面的代码设置Visible = true。

这就是导致我错误的原因:似乎因为容器(TR SpecialRow)是Visible = false,我想有些东西没有渲染。然后我在OnItemDataBound中出现,确定必须显示此行,并设置Visible = true并设置我的HiddenField的值。繁荣。 如果我删除隐藏字段的标记并且不设置其值,则不会崩溃。 所以它不仅仅是TR自身的可见性,它也是HiddenField。

我的修复:不要在标记中设置Visible = false,并在需要时更改OnItemDataBound以设置Visible = false。

换句话说:我默认隐藏标记中的内容并使用后面的代码来显示它们。我改变了这个并在标记中默认显示内容并使用后面的代码隐藏它们。

我在上面的标记和代码中添加了修复程序。