ASP.NET DataSource Control "не имеет контейнера именования" исключение
Я получил это исключение в своем коде и подумал, может ли кто-нибудь мне помочь.
У меня есть элемент управления повторителя, связанный с ObjectDataSource, и шаблон элемента для повторителя содержит пользовательский элемент управления (ASCX). Этот пользовательский элемент управления, в свою очередь, содержит несколько других элементов управления, в основном GridView, связанный с ObjectDataSource.
При первоначальном использовании элементов управления в этой настройке все работает отлично - данные отображаются правильно. Однако, когда я изменяю параметр фильтра (выпадающий список за пределами повторителя), а затем перепривязываю повторитель, я получаю исключение:
Элемент управления ObjectDataSource 'expDataSource' не имеет контейнера именования. Убедитесь, что элемент управления добавлен на страницу перед вызовом DataBind."На System.Web.UI.WebControls.DataBoundControlHelper.FindControl(Control control, String controlID) ... ... на System.Web.UI.WebControls.ObjectDataSource.LoadCompleteEventHandler(Отправитель объекта, EventArgs e)
Я не уверен, в чем проблема - я читал в нескольких местах, что перемещение источника данных за пределы элемента управления ASCX может помочь - это ничего не делает. Источник данных объекта выглядит правильно структурированным, и, как я уже сказал, он работает с первого раза (только).
Я заметил в трассировке стека исключение, что это происходит, когда ASP.NET вызывает FindControl() после выполнения LoadComplete(). Если я перебираю свой код, кажется, что весь мой код завершает выполнение до того, как это произойдет, так что это весь "системный" код.
Почему ASP.NET не сможет найти этот элемент управления источником данных в обработчике LoadComplete?
Спасибо!
Другие заметки:
Эта ошибка возникает через раз. Таким образом, в первый раз данные загружаются правильно, а затем при втором обновлении происходит сбой с этой ошибкой. Нажмите "Загрузить" еще раз, он работает (в третий раз).
В тот момент, когда происходит сбой, похоже, что "Page_Load" вызывается дважды в элементе управления ASCX. Итак, шаблоны:
- Рабочая модель:
- Page_Load на родительской странице
- Page_Load на ASCX
Загрузка данных в порядке
- Плохая картина:
- Page_Load на родительской странице
- Page_Load на ASCX
- Page_Load на ASCX
- исключение
Все это происходит от вызова Repeater.DataBind(), но он ведет себя по-разному в зависимости от того, был ли он уже связан или нет (очевидно).
Больше примечаний:
Реальное странное поведение. Я удалил список SelectParameters из нижней части ObjectDataSource, и внезапно страница не отклоняет ObjectDataSource как не имеющий NamingContainer. Конечно, без этих параметров привязка данных не будет работать... Я могу добавить их в код, но почему это важно?
4 ответа
Нашел странное решение, которое я опубликую, и мы можем обсудить, возможно, выяснить, почему это исправило это.
На моей странице была следующая структура (несколько перефразируя теги):
страница
DropDownFilter
повторитель
UserControl X
ObjectDataSource
ControlParameters Ссылка на DropDownFilter
End ObjectDataSource
End UserControl X
Конец повторитель
Конечная страница
Итак, как вы можете видеть, в Repeater ItemTemplate был пользовательский элемент управления, который в свою очередь имел "виновный" ObjectDataSource с ControlParameters. Эти параметры элемента управления имеют имя фильтра DropDownList на родительской странице, на который ссылаются (поэтому, в основном, если этот элемент управления был добавлен на любую другую страницу, он, конечно, потерпит неудачу, если не сможет найти элемент управления с правильным именем).
Поэтому, когда я прошел и изменил все ControlParameters на Parameters (удалил ссылку на этот элемент управления DropDownList), теперь я больше не получаю ошибку.
Все, что я могу предположить, это то, что тот факт, что этот источник данных ссылался на элемент управления на родительской странице, означал, что у него возникли проблемы при добавлении обратно в набор элементов управления страницы в DataBind(). Вы бы подумали, что в первый раз он потерпит неудачу, если вообще потерпит неудачу, так что это все еще загадка.
Какие-нибудь мысли?
Это исключительная ошибка в ASP.NET DataControls. У меня была похожая проблема, и я потерял несколько месяцев из-за этой эксцентричной ошибки, но, наконец, нашел решение. Причина в том, Чтобы отобразить элементы в ItemTemplate, мы должны использовать серверный элемент управления в LayoutTemplate, который будет выполнять роль заполнителя для ItemTemplate. Например, мы могли бы использовать элемент управления Table/Div со свойством ID в шаблоне макета. Во время выполнения этот элемент управления заполнителем будет заменен содержимым ItemTemplate, и "ошибка контейнера именования" исчезнет. Наконец, если у вас есть objectDataSource в ItemTemplate, убедитесь, что вы добавили что-то (например, table/Div) со свойством "Id" в Layout Template.
Спасибо, Сунил.
Рэй ударил ногтем по голове. Вам определенно не хватает "if(!IsPostBack)" где-нибудь. Как вы добавляете пользовательский элемент управления в ретранслятор? Это динамично? Вы говорите, что это в ItemTemplate, так что, вероятно, нет... Но несколько вызовов Page_Load подразумевают несколько копий элемента управления.
Используйте оба DataBind. Пример:
SqlDataSource1.DataBind();
ListView1.DataBind();