Кнопка TemplateField, вызывающая недопустимый обратный вызов GridView

Хорошо, поэтому у меня есть поле шаблона в gridview, содержащем просто простую кнопку...

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Administration.aspx.cs"     
Inherits="Administration" %>
<%@ Register TagPrefix="ajaxToolkit" Namespace="AjaxControlToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">    
    <title>Keywords Administration</title>
</head>
<body class="popupbody">
<form id="form1" runat="server">
    <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server" EnablePartialRendering="true" CombineScripts="false"></ajaxToolkit:ToolkitScriptManager>

    <asp:Label ID="AddLabel" runat="server">Add a Keyword</asp:Label>
    <br />
    <asp:TextBox ID="AddTextBox" runat="server" />
    <asp:Button ID="AddButton" Text="Add" runat="server" OnClick="AddKeyword_Click" />

    <asp:GridView ID="KeywordsGridView" AllowPaging="false" AutoGenerateColumns="false" BackColor="white"
        GridLines="None" HeaderStyle-CssClass="Table_Header" RowStyle-CssClass="Table_Style" 
        OnRowDataBound="RowBound" runat="server">
        <Columns>
            <asp:TemplateField>
                <ItemTemplate>
                    <asp:Button runat="server" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:BoundField DataField="References" SortExpression="References" HeaderText="Total References" />
            <asp:BoundField DataField="Keyword" SortExpression="Keyword" HeaderText="Keyword" />
        </Columns>
    </asp:GridView>
</form>
</body>
</html>

Всякий раз, когда я нажимаю кнопку, я получаю ошибку...

Invalid postback or callback argument.  Event validation is enabled using 
<pages enableEventValidation="true"/> in configuration or <%@ Page 
EnableEventValidation="true" %> in a page.  For security purposes, this feature 
verifies that arguments to postback or callback events originate from the server 
control that originally rendered them.  If the data is valid and expected, use the 
ClientScriptManager.RegisterForEventValidation method in order to register the 
postback or callback data for validation. 

Я нашел приличное количество статей, ссылающихся на эту проблему, включая пару на SO, например...

Недопустимый аргумент обратной передачи или обратного вызова. Проверка событий активируется с использованием "< pages enableEventValidation =" true "/ > "

и...

Недопустимый аргумент обратной передачи или обратного вызова

Возможно, я просто недопонимаю, но, насколько я могу судить, они мне не помогают. Как мне заставить это уйти без установки enableEventValidation = "false"?

EDIT Отправленный весь код для моей страницы.

Ответ 1

Этот партнер нашел решение аналогичной проблемы (прокрутите вниз до примерно 4-го комментария), который должен был установить уникальный идентификатор для GridView кнопки.

Ответ 2

Я знаю, что этот пост старый, но у меня также была эта проблема в последнее время. После проверки того, как был создан код для asp: ButtonField, а также для кнопки asp:, которую я добавил в ItemTemplate, я обнаружил довольно большую разницу:

жерех: ButtonField: input type="button" onclick = "javascript: __ doPostBack ('ctl00 $ctl00 $cphMain $cphContent $gvEmails', 'SendFromBatch $0')" value = "Продолжить" >

жерех: Кнопка: input id = "ctl00_ctl00_cphMain_cphContent_gvEmails_ctl02_btnCont" type = "submit" onclick = "FreezeScreen ('Письма отправляются...');" value = "Продолжить" name= "ctl00 $ctl00 $cphMain $cphContent $gvEmails $ctl02 $btnCont" >

Тип был проблемой! Итак, после того, как я изменил UseSubmitBehavior с "Отправить" на "False", я больше не получил ошибку.

EDIT: Недавно мне захотелось перейти от обычного btns к imgBtns, чтобы я мог сэкономить некоторое пространство, а также сделать gridview более приятным: D. Конечно, у меня возникла такая же проблема, и у образаbtn нет свойства UseSubmitBehavior, поэтому я начал искать решение.

Найдено следующее (Код приведен в UserControl).

1) Привяжите! IsPostBack

2) Зарегистрируйте сам пользовательский контроль в Render

и все работает так же, как и планировалось - никаких ошибок проверки.

    protected void Page_Load(object sender, EventArgs e)
    {
        OnLoadingEvent(new EventArgs());

        if (!Page.IsPostBack)
        {
            gvEmails.DataSource = odsEmails;
            try
            {
                gvEmails.DataBind();
            }
            catch (Exception)
            {
            }
        }

        if (!writeText) divWriteEmail.Visible = false;
    }

    protected override void Render(HtmlTextWriter writer)
    {
        Page.ClientScript.RegisterForEventValidation(this.UniqueID);

        base.Render(writer);
    }

EDIT: Я играл с приведенным выше кодом и спрашивал себя: что делать, если вам действительно нужно перезагрузить свой объектный источник данных - что происходит потом? Ну, код выше не будет работать, если вы переустановите загрузку страницы, потому что gridview будет снова отскакивать, когда вы нажмете btn в строке gridview, и он не будет распознан как сгенерированный на сервере. Яркий и квадратный, но как избежать такого поведения? Ну... я понял способ, может быть, не самый лучший, но он делает трюк.

На самом деле, вы не хотите переустанавливать gridview, когда вы нажимаете btn на строке gv... но откуда мы знаем, что, поскольку метод загрузки страницы сначала называется? Ну, на самом деле, я не хочу переустанавливать gridview, если параметр выбора источника данных объекта не изменяется. Таким образом, я сохраняю параметр выбора objectDataSource в представлении сеанса, и я возвращаю свой gridview только тогда, когда один из них изменяется - это поведение происходит только во время события PageLoad. Чтобы увидеть последние строки, я нажимаю обновление и получаю последние строки без проблем, и на данный момент я нажимаю gvRow btn, ошибка исчезает.

Чтобы все это произошло, вы должны

  • Непосредственно вызовите .Select() источника данных объекта
  • Поймайте событие OnSelecting из источника данных, сохраните параметр выбора, установите e.Cancel = true
  • Проверьте, не отличаются ли параметры выбора, а затем привязывают gridview, и на этот раз, когда вы ловили OnSelecting, вам нужно установить e.Cancel = false для извлечения данных из БД - только один раз.

Надеюсь, это поможет!

Ответ 3

Сегодня у меня была аналогичная ошибка, но с другим решением. Я работал с gridviews уже много лет, и у меня никогда не было проблемы, поэтому я решил, что это должно быть что-то глупое. Оказывается, я забыл поместить мой код, который загружает gridview в блок if(!Page.IsPostBack), из-за которого кнопка была воссоздана после того, как я щелкнул ее, что вызвало ошибку. Размещение кода загрузки в указанном блоке устранило проблему.

Ответ 4

Вам нужно указать свою кнопку ID. Просто runat = "server" не соответствует минимальной информации, которая должна быть предоставлена ​​для создаваемого серверного элемента управления.