views:

944

answers:

3

I've been getting this exception in my code and wondered if anyone could help me out.

I have a Repeater Control bound to an ObjectDataSource, and the itemtemplate for the repeater contains a User Control (ASCX). This user control in turn contains several other controls, mainly a GridView that is associated with an ObjectDataSource.

On initial use of the controls in this setup, everything works great - data displays properly. However, when I change a filter option (dropdowns outside of the repeater), and then rebind the Repeater, I get the exception:

The ObjectDataSource control 'expDataSource' does not have a naming container. Ensure that the control is added to the page before calling DataBind." at System.Web.UI.WebControls.DataBoundControlHelper.FindControl(Control control, String controlID) ... ... at System.Web.UI.WebControls.ObjectDataSource.LoadCompleteEventHandler(Object sender, EventArgs e)

I'm not sure what the problem is - I've read in a few places that moving the datasource outside of the ASCX control might help - this does nothing. The objectdatasource appears to be properly structured, and as I said, it works the first time (only).

I noticed in the stack trace for the exception that this is occurring when ASP.NET is calling FindControl() after LoadComplete() occurs. If I step through my code, it appears as though all my code is finished executing before this happens, so it's all "system" code.

Why would ASP.NET not be able to find this datasource control in the LoadComplete Handler?

Thanks!

Other Notes:

  • This error occurs every other time. So the first time the data loads properly, then on second refresh fails with this error. Clicking "Load" again, it works (on the third time).

  • On the times that it fails, it looks like "Page_Load" is being called twice in the ASCX control. So the patterns are:

  • Working Pattern:

  • Page_Load on Parent Page
  • Page_Load on ASCX
  • Data Loads fine

  • Failing Pattern:

  • Page_Load on Parent Page
  • Page_Load on ASCX
  • Page_Load on ASCX
  • Exception

This is all happening from a call to "Repeater.DataBind()", but it behaves differently depending on if it has already been bound or not (evidently).

More Notes:

Real strange behavior. I removed the list of SelectParameters from the bottom of the ObjectDataSource, and all of a sudden, the page does not reject the ObjectDataSource as not having a NamingContainer. Of course, without these parameters, Databinding won't actually work...I can add them in the code, but why would it matter?

A: 

Ray hit the nail on the head. You are definitely missing an "if(!IsPostBack)" somewhere. How are you adding the user control to the repeater? Is it dynamic? You say it's in the ItemTemplate, so probably not... But multiple calls to Page_Load imply multiple copies of the control.

Bryan
Bryan - the control is actually declared in the ASPX itself - not added in the code. So I'm guessing the reason for the 2 PageLoads is because:1. First Page_Load called as usual2. DataBind called on Repeater from button event control3. Repeater repopulates and re-adds controls, so Page_Load called again on controlRegardless, I did find a strange solution to this, which I'll post some details about.
Sam Schutte
A: 

Found a strange solution, that I'll post and we can discuss to maybe figure out why this fixed it.

On my page, I had the following structure (paraphrasing the tags somewhat):

Page

DropDownFilter

Repeater

UserControl X

ObjectDataSource

ControlParameters Referencing DropDownFilter

End ObjectDataSource

End UserControl X

End Repeater

End Page

So as you can see, within the Repeater ItemTemplate was the user control, which in turn had the "guilty" ObjectDataSource with ControlParameters. These control parameters had the name of the DropDownList filter on the parent page referenced (so basically, if this control was added to any other page, it would of course fail if it couldn't find a control with the proper name).

So when I went through and changed all the ControlParameters to Parameters (removed the reference to that DropDownList control), now I no longer get the error.

All I can assume is that the fact that this datasource referenced a control on the parent page meant that it was having trouble getting added back to the page's control set on a DataBind(). You would have thought it would fail the first time if it was going to fail at all, so that's still a mystery.

Any thoughts?

Sam Schutte
Honestly... no clue. The fact it didn't happen with ViewState off is what made me think you are just doing one too many data bindings. The controls inside the repeater are recreated each time you bind, which is one reason why you'd get multiple Page_Loads. After a postback, the controls are recreated from ViewState. Then another (inappropriate) call to DataBind gives you the second Page_Load. I'm not too familiar with the ObjectDataSource control. This sort of issue is exactly why I like to do all my binding explicitly in code behind. :) No behind-the-scenes magic to account for!
Bryan
Bryan - yeah, I tend to use a mix of built-in and behind the scenes controls, depending on what I'm doing. Everywhere else on the page, I'm doing my own binding in the code, but I'm using the ObjectDataSource for binding this particular GridView, because it handles so many of the editing/sorting/etc. with minimal effort. Usually I have pretty good luck with them, but of course this page is getting pretty complicated too.You're definitely right about the reasons for the multiple Page_Loads, the strange thing is why the second one would fail while the first one works.
Sam Schutte
A: 

Hi, This is an exceptional error in ASP.NET DataControls. I had similar problem and lost few months behind this eccentric error, but finally got the solution. The reason is; To display items in ItemTemplate, we should use a server control in the LayoutTemplate to act as the placeholder for the ItemTemplate. For example, we could use a Table/Div control with an ID Property in Layout Template. At run time, this placeholder control will be replaced with the contents of the ItemTemplate and "naming container error" will be disappeared. Finally, if you are having an objectDataSource in ItemTemplate, make sure that you added somthing(like table/Div) with "Id" property in Layout Template.

Thanks, Sunil.

Sunil Kumar