Неверный аргумент обратной передачи или обратного вызова (HiddenField и container Visible=false)
Я не нашел ответов, соответствующих моим обстоятельствам, поэтому я публикую ответ на вопрос, надеясь, что он поможет другим.
Я получаю ошибку
Неверный аргумент обратной передачи или обратного вызова. Проверка события включена с использованием в конфигурации или <% @ 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)
У меня есть ListView, связанный с данными (с несколькими строками 100 с), с кнопками в каждой строке. Кнопки приносят всплывающее окно. Во всплывающем окне есть выпадающие списки и другие элементы управления, выполняющие асинхронные обратные передачи. Мне нужно убедиться, что я делаю асинхронные обратные вызовы, чтобы избежать обновления моей большой таблицы.
Я получаю сообщение об ошибке, когда нажимаю кнопку в одной строке, а затем изменяю выпадающий список внутри всплывающего окна, которое запускает обратную передачу (выбранный элемент изменен). Boom.
Вот разметка для уменьшенного образца, без всплывающих окон и 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 ответ
Первоначально я думал, что мой javascript был виноват, поскольку я изменяю вещи с ним. Однако процесс создания образца страницы помог мне найти проблему.
Оказывается, это не имеет никакого отношения к JavaScript или всплывающему окну. Это связано с HiddenField, содержащимся внутри TR HtmlControl (серверный элемент управления asp.net) с Visible=false IN MARKUP. Затем я использую код, чтобы установить Visible=true, когда мне нужно в событии OnItemDataBound.
Вот что вызывает у меня ошибку: кажется, что поскольку контейнер (TR SpecialRow) имеет видимость = ложь, я думаю, что-то не отображается. Затем я захожу в OnItemDataBound, решаю, что эта строка должна быть показана, и устанавливаю Visible=true и устанавливаю значение моего HiddenField. Boom. Если я удалю разметку для скрытого поля и не установлю его значение, не произойдет сбоя. Так что это не только видимость TR самостоятельно, но и HiddenField.
Мое исправление: не устанавливайте Visible = false в разметке и меняйте OnItemDataBound на Visible = false, когда это необходимо.
Другими словами: я по умолчанию скрывал вещи в разметке и использовал код, чтобы показать их. Я изменил это вокруг и по умолчанию показываю вещи в разметке и скрываю их, используя код позади.
Я добавил исправление в разметку и код выше.