Элементы ListBox, переставленные с помощью JavaScript, вызывают ошибку проверки события при обратной передаче - PullRequest
5 голосов
/ 17 октября 2008

Я создал элемент управления обменом элементами, состоящий из двух списков и нескольких кнопок, которые позволяют мне менять элементы между двумя списками. Обмен осуществляется с помощью JavaScript. Я также перемещаю элементы вверх и вниз в списке. Обычно, когда я перемещаю элементы в поле списка справа, я храню ключи данных элементов (GUID) в скрытом поле. При обратной передаче я просто читаю GUID с поля. Все отлично работает, но при обратной передаче я получаю следующее исключение:

Неверный аргумент обратной передачи или обратного вызова. Проверка события включена с использованием в конфигурации или <% @ Page EnableEventValidation = "true"%> на странице. В целях безопасности эта функция проверяет, что аргументы для событий обратной передачи или обратного вызова исходят от серверного элемента управления, который первоначально их представил. Если данные действительны и ожидаемы, используйте метод ClientScriptManager.RegisterForEventValidation, чтобы зарегистрировать данные обратной передачи или обратного вызова для проверки.

Я подготовил тестовое приложение. Все, что вам нужно сделать, это загрузить архив и запустить проект. На веб-странице выберите 3 элемента, нажмите Добавить все, затем переместите третий элемент на один уровень вверх и нажмите «Кнопка». Ошибка появится. Отключение валидации событий ни в коем случае не допустимо. Кто-нибудь может мне помочь, я уже два дня не могу найти решение.

ЗАЯВКА НА ИСПЫТАНИЕ

Ответы [ 7 ]

3 голосов
/ 17 октября 2008

Проблема в том, что сохраненное состояние просмотра списка и данные, полученные при обратной передаче, не совпадают. Проблема проверки события, скорее всего, является лишь одной из возможных проблем, которые могут возникнуть из-за этого подхода. Архитектура веб-форм не допускает такого использования, и, скорее всего, с этим подходом будет больше проблем, даже если вам удастся избежать проблемы проверки события. У вас есть несколько вариантов:

1) Самое простое - это сделать логику обмена на сервере вместо использования javascript. Таким образом, состояние представления будет сохраняться между обратными передачами, и дополнительные издержки нескольких обращений к серверу могут не быть проблемой.

2) Если возникает проблема с многократными обращениями к серверу, напишите серверный элемент управления, который обрабатывает свое собственное состояние просмотра. Это, конечно, очень интересный подход.

3) Средним подходом может быть использование двух простых html-списков (просто напишите html-тэги без использования элементов управления asp.net) и сохранение на стороне клиента javascript списка идентификаторов в скрытом поле. При обратной записи просто проанализируйте скрытое поле и извлеките идентификатор, игнорирующий HTML-списки.

Я бы пошел с 1, если нет серьезных аргументов против него.

1 голос
/ 18 октября 2008

Несколько возможных вариантов:

  • Если возможно, отключите ViewState в двух списках. Без ViewState сервер не будет знать, какие были исходные значения, и, следовательно, не будет ошибки. При таком подходе вам потребуется заново заполнить списки (из-за отсутствия ViewState) и, возможно, потребуется отслеживать выбор вручную - или вам нужно будет заполнить списки во время фазы OnInit.

  • Отключить проверку события (если вы можете)

  • Заполните оба списка полностью на стороне сервера и используйте клиентский сценарий (javascript) для удаления записей из двух списков по мере необходимости.

0 голосов
/ 19 ноября 2015

Вы можете переопределить событие Render, чтобы зарегистрировать все возможные элементы списка в обоих списках. Таким образом, независимо от того, куда какие элементы перемещены, проверка ожидает их.

protected override void Render(HtmlTextWriter writer)
{
  foreach (DictionaryEntry entry in ColumnConfig) {          
    Page.ClientScript.RegisterForEventValidation(lstbxColumnsToExport.UniqueID,(string)entry.Key);
    Page.ClientScript.RegisterForEventValidation(lstbxNonExportColumns.UniqueID,(string)entry.Key);
  }
  base.Render(writer);
}
0 голосов
/ 22 ноября 2011

В качестве альтернативы вы можете использовать серверный HtmlSelect вместо ListBox, чтобы обойти проблему проверки события. Лучше всего то, что вы можете оставить большую часть вашего кода в неизменном виде (т. Е. Логика заполнения списка такая же, как ListBox).

<select runat="server" id="myList" multiple="true" />
0 голосов
/ 19 октября 2008

Случайно, вы уже пробовали это? Делайте это всякий раз, когда вы гадите со списком любым способом.

document.getElementById("listbox").selectedIndex = -1;
0 голосов
/ 17 октября 2008

Первый вариант принесет значительные накладные расходы. Я определил свой собственный элемент управления listbox, полученный из класса listbox, и выполнил переопределение данных loadpostback:

public class CustomListBox : ListBox
{
    protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
    {
        return true;
    }
}

Использование этой функции вместо обычного списка в моем пользовательском элементе управления решило проблему, однако есть ли риски, связанные с моим подходом?

0 голосов
/ 17 октября 2008

Жалуется, потому что выбранный элемент в списке не присутствовал в списке при его рендеринге. Подумайте об использовании PageMethods через AJAX, чтобы вернуть ваши данные в форму вместо PostBack. Или используйте элементы управления без ввода для хранения данных - например, неупорядоченные списки, между которыми вы перемещаете элементы списка. Вы можете поместить GUID в скрытые области внутри элемента списка, где вы можете получить их при необходимости.

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