I am new to the C# XmlSerializer so I might be missing something basic here.
The problem I am running into is that I have one class that has a List<T>
of another class. When I serialize the main class the XML looks beautiful and all the data is intact. When I deserialize the XML, the data in the List<T>
disappears and I am left with an empty List<T>
. I am not receiving any errors and the serialization portion works like charm.
What am I missing with the deserialization process?
EDIT: Note that the code shown below does not reproduce the problem - it works. This was a simplified version of the real code, which did not work. Unfortunately, the code below was simplified enough to not reproduce the problem!
public class User
{
public User()
{
this.Characters = new List<Character>();
}
public string Username { get; set; }
public List<Character> Characters { get; set; }
}
public class Character
{
public Character()
{
this.Skills = new List<Skill>();
}
public string Name { get; set; }
public List<Skill> Skills { get; set; }
}
public enum Skill
{
TreeClimber,
ForkliftOperator
}
public static void Save(User user)
{
using (var textWriter = new StreamWriter("data.xml"))
{
var xmlSerializer = new XmlSerializer(typeof(User));
xmlSerializer.Serialize(textWriter, user);
}
}
public static User Restore()
{
if (!File.Exists("data.xml"))
throw new FileNotFoundException("data.xml");
using (var textReader = new StreamReader("data.xml"))
{
var xmlSerializer = new XmlSerializer(typeof(User));
return (User)xmlSerializer.Deserialize(textReader);
}
}
public void CreateAndSave()
{
var character = new Character();
character.Name = "Tranzor Z";
character.Skills.Add(Skill.TreeClimber);
var user = new User();
user.Username = "Somebody";
user.Characters.Add(character);
Save(user);
}
public void RestoreAndPrint()
{
var user = Restore();
Console.WriteLine("Username: {0}", user.Username);
Console.WriteLine("Characters: {0}", user.Characters.Count);
}
The XML generated by executing CreateAndSave() looks like so:
<User>
<Username>Somebody</Username>
<Characters>
<Character>
<Name>Tranzor Z</Name>
<Skills>
<Skill>TreeClimber</Skill>
</Skills>
</Character>
<Characters>
</User>
Perfect! That's the way it should look. If I then execute RestoreAndPrint()
I get a User object with the Username property set properly but the Characters property is an empty list:
Username: Somebody
Characters: 0
Can anybody explain to me why the Characters property is serialized properly but won't deserialize?
Cannot reproduce; I get (after fixing the more immediate bugs):
Username: Somebody
Characters: 1
Changes:
WriteLine
instead of WriteFormat
(which prevented it compiling)CreateAndSave
from working):
public User() { Characters = new List<Character>(); }
public Character() { Skills = new List<Skill>(); }
In the past, when serializing lists, I've used the [XmlArray] and [XmlArrayItem] annotations. You would then put an [XmlIgnore] annotation on the Characters property. In your case, it would look something like this:
[XmlArray("Characters")]
[XmlArrayItem("Character", Type=typeof(Character))]
public Character[] _ Characters
{
get
{
//Make an array of Characters to return
return Characters.ToArray();
}
set
{
Characters.Clear();
for( int i = 0; i < value.Length; i++ )
Characters.Add( value[i] );
}
}
Hope that helps.
I know this is old but i have the same problem.
What i found is that if i have an object that implements IXmlSerializable in the graph (so the main object that i want to deserialize dosen't implement the interface, but an object in it implements it), it ruins all the deserialization. Lists don't deserialize anymore, neither the object i'm talking about. Serialization works perfect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With