ASP.NET DataSource控件“没有命名容器”异常

时间:2009-11-16 15:44:43

标签: asp.net data-binding datasource exception naming-containers

我在代码中遇到了这个异常,并想知道是否有人可以帮助我。

我有一个与ObjectDataSource绑定的Repeater Control,并且转发器的itemtemplate包含一个用户控件(ASCX)。该用户控件又包含几个其他控件,主要是与ObjectDataSource关联的GridView。

在此设置中初次使用控件时,一切都很有效 - 数据显示正常。但是,当我更改过滤器选项(转发器之外的下拉列表),然后重新绑定Repeater时,我得到例外:

ObjectDataSource控件'expDataSource'没有命名容器。确保在调用DataBind之前将控件添加到页面中。“ 在System.Web.UI.WebControls.DataBoundControlHelper.FindControl(控件控件,字符串controlID) ... ... 在System.Web.UI.WebControls.ObjectDataSource.LoadCompleteEventHandler(Object sender,EventArgs e)

我不确定问题是什么 - 我在一些地方读过,将数据源移到ASCX控件之外可能会有所帮助 - 这没有任何作用。 objectdatasource似乎是正确的结构,正如我所说,它是第一次(仅)。

我在堆栈跟踪中注意到,当发生LoadComplete()之后ASP.NET正在调用FindControl()时发生这种情况。如果我单步执行代码,看起来好像我的所有代码都在执行之前就完成了,所以它就是所有“系统”代码。

为什么ASP.NET无法在LoadComplete处理程序中找到此数据源控件?

谢谢!

其他注释:

  • 此错误每隔一段时间发生一次。因此,第一次正确加载数据时,第二次刷新会因此错误而失败。再次单击“加载”,它可以工作(第三次)。

  • 在失败的时候,看起来在ASCX控件中调用了两次“Page_Load”。所以模式是:

    1. 工作模式:
  • 父页面上的Page_Load
  • ASCX上的Page_Load
  • 数据加载

    1. 失败模式:
  • 父页面上的Page_Load
  • ASCX上的Page_Load
  • ASCX上的Page_Load
  • 异常

这一切都发生在对“Repeater.DataBind()”的调用中,但它的行为会有所不同,具体取决于它是否已被绑定(显然)。

更多备注:

真正奇怪的行为。我从ObjectDataSource的底部删除了SelectParameters列表,突然之间,该页面没有拒绝ObjectDataSource,因为没有NamingContainer。当然,没有这些参数,数据绑定实际上不会起作用......我可以在代码中添加它们,但为什么它会重要?

4 个答案:

答案 0 :(得分:3)

找到一个奇怪的解决方案,我会发布,我们可以讨论,也许可以弄清楚为什么修复它。

在我的页面上,我有以下结构(稍微解释标签):

DropDownFilter

中继器

UserControl X

的ObjectDataSource

引用DropDownFilter的ControlParameters

结束ObjectDataSource

结束UserControl X

结束中继器

结束页

正如您所看到的,在Repeater中,ItemTemplate是用户控件,而后者又拥有带有ControlParameters的“有罪”ObjectDataSource。这些控制参数在引用的父页面上具有DropDownList过滤器的名称(所以基本上,如果将此控件添加到任何其他页面,如果它找不到具有正确名称的控件,它当然会失败。)

因此,当我通过并将所有ControlParameters更改为Parameters(删除对该DropDownList控件的引用)时,现在我不再收到错误。

我可以假设的是,这个数据源在父页面上引用了一个控件,这意味着它在添加回DataBind()上的页面控件集时遇到了麻烦。如果它真的失败了,你会认为它会第一次失败,所以这仍然是一个谜。

有什么想法吗?

答案 1 :(得分:2)

这是ASP.NET DataControls中的一个特殊错误。我有类似的问题,并在这个古怪的错误背后丢失了几个月,但终于得到了解决方案。原因是;要在ItemTemplate中显示项目,我们应该使用LayoutTemplate中的服务器控件作为ItemTemplate的占位符。例如,我们可以在布局模板中使用带有ID属性的Table / Div控件。在运行时,此占位符控件将替换为ItemTemplate的内容,“命名容器错误”将消失。                                                            最后,如果你在ItemTemplate中有一个objectDataSource,请确保在布局模板中添加了带有“Id”属性的somthing(如table / Div)。

谢谢, 苏尼。

答案 2 :(得分:1)

雷击中了头上的钉子。你肯定错过了“if(!IsPostBack)”某个地方。如何将用户控件添加到转发器?它是动态的吗?你说它在ItemTemplate中,所以可能不是......但是对Page_Load的多次调用意味着控件的多个副本。

答案 3 :(得分:1)

同时使用DataBind。例如:

SqlDataSource1.DataBind();
ListView1.DataBind();