Friday, April 15, 2011

ASP.NET: Databinding and updating objects with nested collections

Hi,

I've made a small example with a "Person" class, which contains a list of Pets. In addition, there'se a simple repository that can save / delete / select Person objects. Now I put a form view (or details view) on my form, choose an object data source which points to my repository. So far it works perfectly, I can create, update, delete people... I can even show my collection of pets in an item template in my view.

But when I am updating a person, my collection of pets is cleared! When I look at the "Updating" event of the object binding source, e.InputParameters contains all my values that I have entered, but the pets collection always contains 0 items. When I look at the Selected event of the object binding source, my e.ReturnValue contains my selected person including pets, which is correct. Any ideas?

Here is my person class and my repository. This is a small sample of what is actually a linq2hibernate project.

public class Person 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public int Age { get; set; } 

    public List<Pet> Pets { get; set; } 

    public Person() 
    { 
        Pets = new List<Pet>(); 
    } 
}

[DataObject] 
public class Repository 
{ 
    List<Person> people = new List<Person>(); 

    public Repository() 
    { 
         //Code to load the person list 
    } 

    public Person FindByID(int ID) 
    { 
        return people.SingleOrDefault(x => x.ID == ID); 
    } 

    public List<Person> FindAll() 
    {                         
        return people; 
    }         

    public void Save(Person person) 
    { 
       // code to save a person 
       // Here you can see a person's pets collection is always empty  
       // when this method is called by the objectdatasource 
    } 

    public void Delete(Person person) 
    { 
    }        

    public void Insert(Person person) 
    { 
    } 
}
From stackoverflow
  • I believe it is by design. The object that gets passed to the Save method is not the same object you are editing. The object binding source creates a new instance of a Person when calling the Save method. It assigns properties using reflection and only those that are set in the keys/values collections. I.e. those that your DetailsView has data bound, specifically from DetailsViewUpdatedEventArgs.Keys, NewValues, and OldValues.

    That makes sense, since you are not updating a Pets collection, only Person record. I suggest, inside the Save you call your FindByID and reassign values from the passed person -- the Pets will stay the same.

    I think it may be possible to have Pets as well. If I understand correctly, it would require to write a custom serializer and mark the Person as Serializable. I haven't tried it though.

0 comments:

Post a Comment