Infinite Loop with ObjectContainerDataSource

Topics: Web Client Software Factory, User Forum
Aug 28, 2007 at 9:44 PM
Edited Aug 28, 2007 at 9:58 PM
Hi all. On my page I'm handling the Selecting even of the ObjectContainerDataSource. In my handler I'm setting the DataSource property of the ObjectContainerDataSource. Pretty straightforward. This was how the advanced page in the ObjectContainerDataSource was set up. However when I bind a drop down list to the data source it creates an infinite loop. Best I can tell here is what's happening.

1. Pre-render is called on the drop down.
2. Databind is called inside of prerender.
3. The selecting event is raised on the data source.
4. I set the DataSource property of the data source object.
5. By setting this property the DataSourceViewChanged event is raised.
6. This event is handled by the drop down list.
7. Inside the drop down list's handler databind is called. GOTO 3.

The best way to see this behavior is to add a drop down list to the advanced page in the ObjectContainerDataSource quick start and bind it to the datasource. It will cause an overflow.

Has anybody else encountered this or is there a fix somewhere for it?

BTW Lutz Roeder's Reflector is awesome.
Aug 29, 2007 at 4:40 PM
Hi again. Allright I've done some more testing on this and discovered that this happens for ListBoxes as well. My guess is that anything that derives from ListControl is going to make this happen.

Also I was able to recreate this behavior by using a SqlDataSource and a DropDownList on a page and then calling Select on the datasource inside of the Selecting event handler. Basically the exact same thing that is happening with the ObjectContainerDataSource.

Surely someone else is having this same issue. I'll probably end up having to alter the ObjectContainerDataSource somehow but I'm not sure what to change. Perhaps having another event for setting the datasource that gets raised if the datasource isn't already set? Any suggestions.

Mar 7, 2008 at 10:43 AM
Hi,

I'm having the exact same problem. Handing the Selecting event of the ObjectContainerDataSource for dropdownlists that are within gridviews and formviews seems to be find. But when the DropdownList is simply in the page it get's into the infinite loop. What's the answer to this? Assistance would be appreciated.

Thanks

Mat
Mar 7, 2008 at 2:32 PM
Well I looked at how some of the other datasources handle this-Reflector is a good thing-when they have the DataSource property set on their view they check to see if the new datasource is different from the old one. Only if it is different is the DataSourceViewChanged event raised. I changed the Datasource property in ObjectContainerDataSourceView to check if the datasource has indeed changed. It looks like this:

private object _dataSource;
public virtual object DataSource
{
set
{
if (_dataSource != value)
{
_dataSource = value;
Data.Clear();

if (value == null)
return;

IEnumerable values = value as IEnumerable;
if (values != null)
{
SafeAddRange(values);
}
else
{
SafeAdd(value);
}
OnDataSourceViewChanged(EventArgs.Empty);
}
}
}
Coordinator
Mar 7, 2008 at 5:07 PM
I'm going to get someone from the team to look into this for you all.

Enjoy,
Michael Puleio - patterns & practices
Webhttp://msdn.microsoft.com/practices/
Bloghttp://blogs.msdn.com/mpuleio/
Mar 14, 2008 at 5:44 PM
Edited Mar 19, 2008 at 12:43 PM
Hi all,

The problem is caused only when using controls derived from ListControl (ListBox, DropDownList, CheckBoxList, …). The ListControl class overrides the method PerfomSelect of its base class DataBoundControl and implements a specific behavior, but the controls derived from CompositeDataBoundControl (DetailsView, FormView, GridView) don’t. In this specific behavior resides the cause of the issue.

The PerformSelect method is executed every time a databound control has to do data binding. In this method, data is retrieved from the data source and it is bound to the control. The PerformSelect method of the DataBoundControl base class sets an internal flag (_ignoreDataSourceViewChanged) that indicates that the DataSourceViewChanged event has to be ignored while the PerformSelect method is being executed. This event is thrown by data source controls when their content changes, and it is typically handled by databound controls to rebind to the new data.

The issue is related with the ListControl implementation of the PerformSelect method, because in this method no flag is set to prevent the handling of the DataSourceViewChanged event during the PerformSelect method execution. Note that this event is raised everytime the DataSource property of the ObjectContainerDataSource control is set.

A new entry has been added to the Know Issues page about this issue: StackOverflowException threw by an infinite loop with ObjectContainerDataSource with details on how to fix it and a quick workaround.

Please let me know if this helps,

Jonathan Cisneros
http://staff.southworks.net/blogs/jcisneros/default.aspx
Mar 14, 2008 at 9:32 PM
Thanks for looking into this jonathan.
Mar 15, 2008 at 10:20 AM
Thanks for looking in to this.

For your interest, to get around the problem, rather than handling the onselect or onload events of the OCDS to load the list data and set teh datasource I instead handled the OnViewInitialized event of the presenter and set the OCDS.DataSource property there. This fixed the problem for me.

Thanks

Mat