XmlSerializer.Deserialize () does not deserialize List <T> correctly

I'm new to C # XmlSerializer, so I might miss something basic here.

The problem I am facing is that I have one class from List<T>another class. When I serialize the main class, the XML looks beautiful and all the data remains intact. When I deserialize the XML, the data List<T>disappears and I leave it blank List<T>. I get no errors, and part of the serialization works like a charm.

What am I missing during the deserialization process?

EDIT: Please note that the code below does not reproduce the problem - it works. It was a simplified version of real code that didn't work. Unfortunately, the code below has been simplified enough not to 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 running CreateAndSave () looks like this:

<User>
  <Username>Somebody</Username>
  <Characters>
    <Character>
      <Name>Tranzor Z</Name>
      <Skills>
        <Skill>TreeClimber</Skill>
      </Skills>
    </Character>
  <Characters>
</User>

Perfect! The way it should look. If I then execute RestoreAndPrint(), I get a User object with the Username property set, but the Characters property is an empty list:

Username: Somebody
Characters: 0

Can someone explain to me why the Characters property serializes correctly but will not deserialize?

+5
source share
8 answers

, , XmlSerializer .

IXmlSerializer ReadXml() WriteXml(). , , IXmlSerializer, , , .

+1

; ( ):

Username: Somebody
Characters: 1

:

  • WriteLine WriteFormat ( )
  • ( CreateAndSave ):
    • public User() { Characters = new List<Character>(); }
    • public Character() { Skills = new List<Skill>(); }
+5

[XmlArray] [XmlArrayItem]. [XmlIgnore] Character Character. :

[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] );
    }
}

, .

+2

, StreamReader XmlReader. , ( ) "var".

public static User Restore()
{
  if (!File.Exists("data.xml"))
    throw new FileNotFoundException("data.xml");

  XmlReader xr = XmlReader.Create("data.xml");
  XmlSerializer serializer = new XmlSerializer(typeof(User));
  var user = (User)serializer.Deserialize(xr);
  xr.Close();
  return user;
}

EDIT: , XmlInclude User.

[XmlInclude( typeof( Character ) )]
+1

, , .

, , IXmlSerializable ( , , , ), , deserialize , , . .

+1
Stream stream = File.Open(filename + ".xml", FileMode.Open);
User user = null;
using (XmlReader reader = XmlReader.Create(stream))
{
    user = IntermediateSerializer.Deserialize<User>(reader, null);
}
stream.Close();

return user;

- .

0

I added this attribute to my list types, and it worked then (had the same problem):

[System.Xml.Serialization.XmlElementAttribute("NameOfMyField")]
public List<SomeType> NameOfMyField{get;set;}

I think this is your decision.

0
source

Perhaps this is due to the deserialization of the enumeration .... since it serialized it as a string value ... there may be a problem creating the correct enumeration value for the character. Did not test this hypothesis ...

-2
source

All Articles