Binding polymorphic collection in ASP.Net

Binding polymorphic collection in ASP.Net

Old forum URL: forums.lhotka.net/forums/t/1582.aspx


skagen00 posted on Tuesday, October 24, 2006

I would love to know if anyone else has accomplished this using a CSLA polymorphic collection.

I have a collection of say, IProfileRole. (of which I might have various types implementing IProfileRole).

ASP.Net responds to databinding to a GridView in ASP.Net: object does not match target type

I have not found the appropriate solution, and I suspect some of you have. Would you please share if you have?

Thank you.

skagen00 replied on Tuesday, October 24, 2006

Just playing around with it a little bit more tonight, it seems like using a collection of polymorphic objects using inheritance with an ASP.Net Gridview but once I change it to be an interface it no longer works.

i.e. if I have car and truck as derived classes of auto and a collection of auto, I can bind this collection containing both types of autos to a GridView. But if car and truck implement IAuto and my collection is of IAuto, binding a collection with different types of IAutos fails.

Obviously since with CSLA interfaces are a popular way polymorphism is implemented and using inheritance for polymorphism not there with generics, the hands are tied a little.

So if anyone has successfully did binding to a grid with an interface collection using ASP.Net, please let me know how you accomplished it, I'd be very appreciative.

Thanks.

ajj3085 replied on Wednesday, October 25, 2006

Does your interface also specify that it must implemnt IEditableBusinessObject or IReadOnlyObject?

For example:

public interface IMyInterface : Csla.Core.IEditableBusinessObject {
// interface definition here
}

skagen00 replied on Wednesday, October 25, 2006

Yep, that's not the problem - it's an ASP.Net GridView issue that I've found scattered posts about. One mentioning ITypedList but I'm not sure that's the trick (maybe I'm implementing it incorrectly as I tried that direction).

Thanks for the thought though.

ajj3085 replied on Wednesday, October 25, 2006

Well some more code from your application would be helpful then.

skagen00 replied on Wednesday, October 25, 2006

Here are the classes/interface:

IBase has two properties, Shared1 and Shared2.

ClassA and ClassB implement IBase and have one other property other than the two in IBase.

I used a simple BindingList<T> & non-CSLA to keep things really simple - the same thing happens with CSLA objects & collections.

Then, just creating a Web site with one page containing a GridView and a button, and placing this code in the button clicked:

MyCollection test = new MyCollection();

ClassA a = new ClassA();

a.Shared1 = 1;

a.Shared2 = 2;

a.ClassAvar = 3;

ClassB b = new ClassB();

b.Shared1 = 55;

b.Shared2 = 66;

b.ClassBvar = 77;

test.Add(a);

test.Add(b);

GridView1.DataSource = test;

GridView1.DataBind();

It will fail, giving that error message from my first post. "Property accessor 'Shared2' on object 'ClassLibrary3.ClassB' threw the following exception:'Object does not match target type.'"  This does not occur in a Windows grid - Windows databinding is more intelligent in this regard it seems.

The classes are shown below:

public interface IBase

{

int Shared1 {get;set;}

int Shared2 { get;set;}

}

public class ClassA : IBase

{

private int _classAvar;

public int ClassAvar

{

get { return _classAvar; }

set { _classAvar = value; }

}

private int _shared1;

public int Shared1

{

get

{

return _shared1;

}

set

{

_shared1 = value;

}

}

private int _shared2;

public int Shared2

{

get

{

return _shared2;

}

set

{

_shared2 = value;

}

}

}

public class ClassB : IBase

{

private int _classBvar;

public int ClassBvar

{

get { return _classBvar; }

set { _classBvar = value; }

}

private int _shared1;

public int Shared1

{

get

{

return _shared1;

}

set

{

_shared1 = value;

}

}

private int _shared2;

public int Shared2

{

get

{

return _shared2;

}

set

{

_shared2 = value;

}

}

}

public class MyCollection : BindingList<IBase>

{

}

ajj3085 replied on Wednesday, October 25, 2006

The interface IBase doesn't inherit Csla.Core.IEditableBusinessObject.   At least in the code you show it doesn't.  Try making suer it does that, and have the collection inherit from BusinessListBase, I think you'll have more success that way (and I assume you want to use Csla, or you wouldn't be here).  Also, make sure ClassA and B inherit BusinessBase (while still implementing your interface).

Those base classes provide a bunch of support for databinding, which none of your code supports (for example, none of your objects implement IPropertyChanged, which BusinessBase does).

Andy

skagen00 replied on Wednesday, October 25, 2006

Thanks Andy, though I have basically broken this down to a common denominator. I have definitely been utilizing CSLA and my first encounter with this had to do with a polymorphic businesslistbase. If one changes the collection to utilize polymorphism with inheritance rather than interfaces, it works.

My sample is basically the "lowest denominator" of code that I can have it exhibit this error. The bottom line appears to be that unless extra accomodations (beyond what IEditableObject and such may give one) made to support data binding with the GridView, collections of interfaces cannot be bound to an ASP.Net GridView if there are differing object types underlying the interface collection.

From what I've read it detects the property set from the first object in the collection, and then when it finds that the second object isn't the same type, it gives the error. You'll note the error hits with the ClassB instance.

If I find the solution I will certainly post it here!

 

Copyright (c) Marimer LLC