обработчик событий управления пользователем потерян при обратной передаче - PullRequest
4 голосов
/ 11 августа 2009

У меня есть меню usercontrol под названием LeftMenu, в котором есть маркированный список ссылок. Это на странице ascx как таковой:

<asp:BulletedList ID="PublisherList" DisplayMode="LinkButton" OnClick="PublisherList_Click" cssClass="Menu" runat="server"></asp:BulletedList>

Я связываю данные в page_load под if(!isPostBack)

У меня проблема на странице, которая загружает элемент управления. При первой загрузке страницы запускается обработчик событий. Однако, когда страница отправляется обратно, она больше не запускается, и в IE8, когда я отлаживаю, я получаю «Ошибка времени выполнения Microsoft JScript: ожидаемый объект» в Visual Studio, указывающий на «__doPostBack ('LeftMenu $ PublisherList', '0') «. В FF я не получаю ошибку, но ничего не происходит. Я не загружаю элемент управления динамически, он загружается на страницу aspx с помощью:

<%@ Register TagPrefix="Standards" TagName="LeftMenu" Src="LeftMenu.ascx" %>

<Standards:LeftMenu ID="LeftMenu" runat="server"/>

Есть идеи, где я теряю обработчик событий?

Я только что понял, что это происходит на другом пользовательском контроле, который у меня есть. Текстовое поле и кнопка, и я использую кнопку по умолчанию, чтобы убедиться, что нажатие клавиши ввода использует эту кнопку. .Net преобразует это в html:

 <div id="SearchBarInclude_SearchBar" onkeypress="javascript:return WebForm_FireDefaultButton(event, 'SearchBarInclude_QuickSearchButton')">

так что, как только я ввожу ключ в поле, я получаю сообщение об ошибке javascript в строке, говорящей «ожидаемый объект». Похоже, что эти два вопроса связаны между собой.

Снова отредактируйте: я думаю, что мне нужно уточнить. Дело не в том, что я нажимаю на пункт меню, и он не может найти выбранный пункт при обратной передаче. У меня есть эта страница поиска с левой навигацией по ней, а затем основное содержание страницы вызывает обратную реакцию. Все хорошо с этим постбэком. Как только эта страница была опубликована, теперь, если я нажимаю на маркированный список в левой навигационной панели, я получаю ошибку javascript, и она терпит неудачу. Page_init для элемента управления LeftMenu никогда не вызывается.

Ответы [ 6 ]

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

У меня была похожая проблема. Оказалось, что Akamai изменяет строку пользовательского агента, потому что применяется параметр, который не нужен.

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

0 голосов
/ 12 августа 2009

Похоже, что функция doPostBack отсутствует, поскольку ее аргументы являются литералами, поэтому они не могут быть причиной. Это одна из ваших собственных функций или вы хотели вызвать функцию ASP __doPostBack?

Посмотрите на консоль ошибок Firefox или разрешите отладку скриптов в IE и посмотрите, какой именно объект не может быть найден. Более того, загрузите Firebug и отладьте его.

0 голосов
/ 12 августа 2009

Я переместил код в существующий проект, который у нас есть, и по какой-то странной причине я перестал получать ошибки JavaScript и вместо этого получил:

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

В целях безопасности эта функция проверяет, что аргументы для событий обратной передачи или обратного вызова исходят от серверного элемента управления, который первоначально их представил. Если данные действительны и ожидаемы, используйте метод ClientScriptManager.RegisterForEventValidation, чтобы зарегистрировать данные обратной передачи или обратного вызова для проверки. "

Я не совсем понял, где я должен поставить валидацию события регистрации с помощью пользовательского элемента управления, но в то же время я просто установил enableeventvalidation=false, и теперь это похоже на работу.

0 голосов
/ 11 августа 2009

Возможно, это связано с javascript и что скрипт, который загружается ранее на странице, выдает ошибку и вызывает неправильную загрузку страницы.

Ваши пользовательские контроллеры загружают какой-либо javascript на страницу? Можете ли вы проверить наличие ошибок JavaScript при начальной загрузке страницы?

0 голосов
/ 11 августа 2009

Если у вас есть EnableViewState = true для вашего UserControl и всех элементов управления внутри него, все должно работать нормально. При включенном ViewState ASP перезапустит ваши элементы управления из ViewState после запуска Init. Это означает, что аргумент события обратной передачи (который указывает на индекс в вашем списке элементов управления) все равно найдет элемент управления в этой позиции списка. В противном случае список пуст при обратной передаче.

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

Если вы имеете дело со статическими или относительно статическими данными, сохраняйте их в кеше приложения и каждый раз перепривязывайте списки в Page.Init (обратите внимание, что это должно быть в Init, потому что post-init - это когда ASP перезапускается из ViewState ; если вы попадете туда первыми, вместо этого будут использованы ваши данные).

Если вы имеете дело с изменчивыми данными, у вас есть проблема, потому что данные, которые вы перепривязываете, должны быть точно такими же, как исходный запрос страницы, в противном случае события обратной передачи будут запускаться против неправильных строк. В этом случае вам нужно либо сохранить исходные данные в сеансе, либо просто сохранить список идентификаторов строк (в скрытой переменной или сеансе), и вы каждый раз воссоздаете данные для привязки по идентификаторам.

Еще лучшее решение - вообще не использовать события обратной передачи. Попробуйте превратить все ваши события в GET, которые имеют идентификатор в строке запроса. Вы все еще можете создать список, используя привязку в первый раз через страницу (как вы делаете в настоящее время), и вы даже можете получить ту же страницу с новым идентификатором.

Если вам нужно сохранить состояние на той же странице, но нужно ответить пользователю, меняющему выбор переключателя (или что-то еще), подумайте об использовании вызовов Ajax для обновления экрана. Вы также делаете это с помощью идентификатора, который вы передаете вызову Ajax.

В целом, чем больше вы отказываетесь от использования ASP с сохранением состояния, тем легче и отзывчивее становятся ваши страницы. Вы также сможете лучше перейти на MVC без сохранения состояния, если это необходимо. Вы также сэкономите много времени, потраченного на отладку непонятных проблем, потому что ViewState недоступен, когда это необходимо.

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

http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/truly-understanding-viewstate.aspx

0 голосов
/ 11 августа 2009

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

Вы должны попытаться снова связать список на PostBack, чтобы посмотреть, решит ли это вашу проблему. НО, что ДЕЙСТВИТЕЛЬНО должно произойти, так это то, что LeftMenu и BulletedList должны хранить свою информацию в ViewState, чтобы вы могли гарантировать, что данные, которые были показаны пользователю при начальной загрузке страницы, - это те же данные, которые PostBack обрабатывает и работает с .

...