Кнопка TemplateField, вызывающая недопустимую обратную передачу GridView - PullRequest
7 голосов
/ 03 июня 2010

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

<%@ 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, например ...

Недопустимый аргумент обратной передачи или обратного вызова. Проверка события включена с помощью ''

и ...

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

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

РЕДАКТИРОВАТЬ Выложил весь код для моей страницы.

Ответы [ 4 ]

12 голосов
/ 23 августа 2012

Я знаю, что этот пост старый, но у меня тоже недавно была эта проблема. После проверки того, как был сгенерирован код для asp: ButtonField, а также для asp: Button, который я добавил в 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 с «Submit» на «False», я больше не получил ошибку.

EDIT: Недавно я хотел перейти с обычных btns на imgBtns, чтобы сэкономить место и сделать сетку более приятной: D. Конечно, у меня возникла та же проблема, и у imagebtn нет свойства 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: Я поигрался с приведенным выше кодом и спросил себя, что, если вам действительно нужно перебросить свой объектный источник данных - что произойдет потом? Хорошо, приведенный выше код не будет работать, если вы перепривязываете при загрузке страницы, потому что представление сетки будет восстановлено снова, когда вы нажмете btn в строке вида сетки, и оно не будет распознано как созданное на сервере. Справедливо и справедливо, но как избежать такого поведения? Ну ... я нашел способ, может быть, не самый лучший, но он делает свое дело.

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

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

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

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

6 голосов
/ 03 июня 2010

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

2 голосов
/ 13 мая 2014

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

0 голосов
/ 03 июня 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...