Отслеживание состояния с использованием ASP.NET AJAX / ICallbackEventHandler

У меня проблема с сохранением состояния на странице ASP.NET AJAX. Краткая версия: мне нужен способ обновить страницу ViewState после выполнения асинхронного обратного вызова, чтобы отразить любые изменения состояния, сделанные сервером во время асинхронного вызова.

Кажется, это обычная проблема, но я опишу свой сценарий, чтобы помочь объяснить:

У меня есть элемент управления в виде сетки, в котором есть некоторые улучшения JavaScript, а именно возможность перетаскивать столбцы и строки. Когда столбец или строка перетаскиваются в новую позицию, вызывается метод AJAX для уведомления на стороне сервера управления и запуска соответствующего события на стороне сервера («OnColumnMoved» или «OnRowMoved»).

Вызовы ASP.NET AJAX по умолчанию отправляют всю страницу в качестве запроса. Таким образом, страница проходит полный жизненный цикл, состояние просмотра сохраняется, а состояние элемента управления восстанавливается до вызова метода RaiseCallbackEvent.

Однако, поскольку вызов AJAX не обновляет страницу, ViewState отражает исходное состояние элемента управления даже после перемещения столбца или строки. Таким образом, во второй раз, когда происходит действие на стороне клиента, запрос AJAX отправляется на сервер, и страница и элемент управления снова создаются для отражения первого состояния элемента управления, а не состояния после перемещения первого столбца или строки.

Эта проблема имеет множество последствий. Например, если у нас есть действие на стороне клиента / AJAX для добавления нового элемента в сетку, а затем перетаскивается строка, сетка строится на стороне сервера с одним элементом меньше, чем на стороне клиента.

И, наконец, что наиболее серьезно для моего конкретного примера, фактический объект источника данных, над которым мы работаем, хранится на странице ViewState. Это было дизайнерское решение, позволяющее сохранить копию обрабатываемых данных с отслеживанием состояния, которую можно либо передать в БД после многих манипуляций, либо отбросить, если пользователь откажется. Это очень сложно изменить.

Итак, мне снова нужен способ обновления страницы ViewState при обратном вызове после запуска метода AJAX.

Ответов (5)

Решение

Если вы все равно перетасовываете ViewState, вы также можете использовать UpdatePanel. Его частичные обратные передачи автоматически обновят ViewState страницы.

Я не понимаю, почему вы должны использовать для этого настраиваемый элемент управления, если встроенный ASP.NET AJAX UpdatePanel делает то же самое.

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

Ознакомьтесь с этим сообщением в блоге: Настройка ICallbackEventHandler и Viewstate . Автор, кажется, обращается к той самой ситуации, с которой вы столкнулись:

Таким образом, при использовании ICallbackEventHandler у вас есть два препятствия, которые необходимо преодолеть, чтобы обновить управление состоянием для обратных вызовов. Во-первых, это проблема состояния просмотра, доступного только для чтения. Другой фактически регистрирует изменения, внесенные пользователем на страницу, перед запуском обратного вызова.

Его предложения о том, как решить эту проблему, можно найти в сообщении в блоге. Также ознакомьтесь с этим сообщением на форуме, в котором также обсуждается та же проблема.

На самом деле я нашел обе предоставленные вами ссылки, но, как уже отмечалось, они просто описывают проблему, а не решают ее. Автор сообщения в блоге предлагает обходной путь, используя другого поставщика ViewState, но, к сожалению, в данном случае это невозможно ... Мне действительно нужно оставить детали ViewState в покое и просто подключиться к тому, что делается прямо из коробки.

Я нашел довольно элегантное решение с помощью Telerik RadAjaxManager . Работает неплохо. По сути, вы регистрируете каждый элемент управления, который может вызывать обратную передачу, а затем регистрируете каждый элемент управления, который должен быть перерисован после того, как эта обратная передача выполняется асинхронно. RadAjaxManager Будет обновлять DOM после асинхронного постбэк и переписать ViewState и все затронутые элементы управления. После принятия заглянуть в Reflector это выглядит немного запутанно под капотом, но он подходит моим целям.