Thoumis Tiechy
Thoumis Tiechy

Reputation: 23

XML deserialize brings back empty list

I have a dictionary of abilityobjects <id, abilityObj> that I'm trying to serialize in XML. Because you can't XML Serialize a dictionary, I change it into a list on serialization

public class BattleSerializable : TyrantSerializable
{
    [XmlIgnoreAttribute]
    [NonSerialized]
    [DoNotSerialize]
    public Dictionary<int, AbilityObjectSerializable> battleObjects;
    
    public List<AbilityObjectSerializable> serializedBattleObjects
    {
        get
        {
            if (battleObjects == null)
            {
                battleObjects = new Dictionary<int, AbilityObjectSerializable>();
            }

            return battleObjects.Select(x => x.Value).ToList();
        }
        set
        {
            battleObjects = value.ToDictionary(x => x.entityId, x => x);
        }
    }

It serializes correctly. I.e. the XML that gets saved makes sense

<BattleSerializable>
    ...
    <serializedBattleObjects>
      <AbilityObjectSerializable xmlns:d3p1="http://www.w3.org/2001/XMLSchema-instance" d3p1:type="FireballObject">
         <hexDirection>southeast</hexDirection>
         <gridX>0</gridX>
         <gridZ>7</gridZ>
         <entityId>3</entityId>
         <lastAnimation>STATUE</lastAnimation>
         <timer>0</timer>
         <abilityPos>2</abilityPos>
         <abilityType>FIREBALL</abilityType>
         <health>100</health>
         <tilesPerTurn>2</tilesPerTurn>
         <jump>1</jump>
         <fall>99</fall>
         <damage>5</damage>
         <lineTraversed>
            <xDisplace>1</xDisplace>
            <zDisplace>-2</zDisplace>
            <endTileFacing>east</endTileFacing>
         </lineTraversed>
         <moveDirection>
            <xDisplace>1</xDisplace>
            <zDisplace>-2</zDisplace>
            <endTileFacing>east</endTileFacing>
         </moveDirection>
      </AbilityObjectSerializable>
    </serializedBattleObjects>
</BattleSerializable>

But when I try to then -load- this XML and turn it into actual C# objects, this list comes in empty for some reason, causing the app to blow up.

What am I missing? All the other lists in this class serialize/deserialize correctly.

My load code:

public BattleSerializable Load(string path)
{
    var serializer = new XmlSerializer(typeof(BattleSerializable));
    try
    {
        using (var stream = new FileStream(path, FileMode.Open))
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(stream);
            string xmlString = xmlDoc.InnerXml;
            BattleSerializable bs = (BattleSerializable)this.LoadFromXML(xmlString);
            return bs;
        }
    }
    catch (Exception e)
    {
        throw new SettingLoadException("Settings failed validation");
    }
}

Upvotes: 2

Views: 116

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1063338

The way a lot of serializers work is by calling Add on a list, only actually assigning anything back to the setter if the serializer created the list (perhaps because it was null, or fixed size such as an array). So imagine the serializer doing:

var list = obj.SomeProperty;
while (moreOfTheSame)
   list.Add(ReadOneOfThose());

It never calls the setter, so any logic in there: irrelevant. You'll probably need a custom list type here, or perhaps more simply: have a nice simple POCO/DTO model that just maps to the serialization shape with no fun logic, and project between this model and your domain model separately to serialization.

Upvotes: 1

Related Questions