【问题标题】:ASP.NET DataSource Control "does not have a naming container" exceptionASP.NET 数据源控件“没有命名容器”异常
【发布时间】:2010-12-17 02:41:58
【问题描述】:

我的代码中出现了这个异常,想知道是否有人可以帮助我。

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

初次使用此设置中的控件时,一切正常 - 数据显示正常。但是,当我更改过滤器选项(中继器外部的下拉菜单),然后重新绑定中继器时,我得到了异常:

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

我不确定问题出在哪里——我在一些地方读到,将数据源移到 ASCX 控件之外可能会有所帮助——这无济于事。 objectdatasource 似乎结构正确,正如我所说,它在第一次(仅)工作。

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

为什么 ASP.NET 在 LoadComplete Handler 中找不到这个数据源控件?

谢谢!

其他说明:

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

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

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

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

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

更多注释:

真正奇怪的行为。我从 ObjectDataSource 的底部删除了 SelectParameters 列表,突然之间,页面不会因为没有 NamingContainer 而拒绝 ObjectDataSource。当然,如果没有这些参数,Databinding 将无法实际工作……我可以将它们添加到代码中,但为什么会重要呢?

【问题讨论】:

  • 听起来您的初始成功加载是使用“GET”请求,而失败发生在“POST”中 - 您是否使用“if (IsPostBack)”以不同方式加载控件或数据?
  • 否 - 两种类型的请求都应该遵循相同的流程。嗯...
  • 我认为初始加载实际上也是一个 POST,因为他们首先从过滤器控件 (DropDowns) 中选择一些选项,然后单击“加载”按钮进行首次加载。
  • 关闭转发器的视图状态是否有效?
  • 是的 - 如果我关闭转发器的 ViewState,错误就会消失。问题是,我需要打开 ViewState,因为我正在添加临时控件(至少没有对此进行一些重大更改)。为什么关闭 ViewState 会使错误消失?

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


【解决方案1】:

找到一个奇怪的解决方案,我将发布它,我们可以讨论以找出解决此问题的原因。

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

页面

下拉过滤器

中继器

用户控件 X

对象数据源

ControlParameters 引用 DropDownFilter

结束对象数据源

最终用户控件 X

结束中继器

结束页面

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

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

我只能假设这个数据源引用了父页面上的控件这一事实意味着它无法通过 DataBind() 重新添加到页面的控件集中。如果它完全失败,你会认为它第一次会失败,所以这仍然是一个谜。

有什么想法吗?

【讨论】:

  • 老实说……不知道。关闭 ViewState 并没有发生的事实让我觉得你只是做了太多的数据绑定。每次绑定时都会重新创建转发器内的控件,这也是您获得多个 Page_Loads 的原因之一。回发后,控件从 ViewState 重新创建。然后对 DataBind 的另一个(不适当的)调用会为您提供第二个 Page_Load。我对 ObjectDataSource 控件不太熟悉。这类问题正是我喜欢在后面的代码中显式进行所有绑定的原因。 :) 无需考虑幕后魔术!
  • Bryan - 是的,我倾向于混合使用内置和幕后控件,这取决于我在做什么。页面上的其他任何地方,我都在代码中进行自己的绑定,但我使用 ObjectDataSource 来绑定这个特定的 GridView,因为它处理了很多编辑/排序/等。用最小的努力。通常我和他们相处得很好,但当然这个页面也变得相当复杂。对于多个 Page_Loads 的原因,您绝对是正确的,奇怪的是为什么第二个会失败而第一个工作。
  • 2015 年,我仍在做 Webforms...(遗留应用程序)。尽管如此:我认为你的假设是正确的。我在父控件上手动调用DataBind() 时遇到了这个问题。将所有 ControlParameters 更改为 Parameters 并在父控件的 ItemDatabound 事件处理程序中填写值 (DefaultValue) 解决了该问题。神秘的方式...
  • 有同样的问题。将指向父页面上的控件的 ControlParameters 更改为常规参数并在后面的代码中手动设置值解决了这个问题。
【解决方案2】:

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

谢谢, 苏尼尔。

【讨论】:

    【解决方案3】:

    雷一针见血。您肯定在某处缺少“if(!IsPostBack)”。您如何将用户控件添加到转发器?是动态的吗?你说它在 ItemTemplate 中,所以可能不是……但是多次调用 Page_Load 意味着控件的多个副本。

    【讨论】:

    • Bryan - 控件实际上是在 ASPX 本身中声明的 - 没有添加到代码中。所以我猜测 2 PageLoads 的原因是因为: 1. 第一个 Page_Load 像往常一样调用 2. DataBind 从按钮事件控件调用 Repeater 3. Repeater 重新填充并重新添加控件,所以 Page_Load 再次调用控件 无论如何,我确实找到了一个奇怪的解决方案,我将发布一些详细信息。
    【解决方案4】:

    同时使用 DataBind。示例:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-12
      相关资源
      最近更新 更多