簡體   English   中英

XmlSerializer.Deserialize()沒有反序列化List <T> 正確地

[英]XmlSerializer.Deserialize() isn't deserializing a List<T> correctly

我是C#XmlSerializer的新手,所以我可能會遺漏一些基本的東西。

我遇到的問題是我有一個類有另一個類的List<T> 當我序列化主類時,XML看起來很漂亮,所有數據都完好無損。 當我反序列化XML時, List<T>的數據消失了,我留下了一個空的List<T> 我沒有收到任何錯誤,序列化部分就像魅力一樣。

反序列化過程中我錯過了什么?

編輯:請注意,下面顯示的代碼不會重現問題 - 它的工作原理。 這是真正的代碼, 沒有工作的簡化版本。 不幸的是,下面的代碼已經足夠簡化,無法重現問題!

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

通過執行CreateAndSave()生成的XML如下所示:

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

完善! 這就是應該看的樣子。 如果我然后執行RestoreAndPrint()我得到一個User對象,其Username屬性設置正確但Characters屬性是一個空列表:

Username: Somebody
Characters: 0

任何人都可以向我解釋為什么Characters屬性被正確序列化但不會反序列化?

無法重現; 我得到(在修復更直接的錯誤之后):

Username: Somebody
Characters: 1

變化:

  • WriteLine而不是WriteFormat (阻止它編譯)
  • 初始化默認構造函數中的列表(阻止CreateAndSave工作):
    • public User() { Characters = new List<Character>(); }
    • public Character() { Skills = new List<Skill>(); }

過去,在序列化列表時,我使用了[XmlArray]和[XmlArrayItem]注釋。 然后,您將在Characters屬性上放置一個[XmlIgnore]注釋。 在你的情況下,它看起來像這樣:

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

希望有所幫助。

我知道這是舊的,但我有同樣的問題。

我發現如果我有一個在圖中實現IXmlSerializable的對象(所以我想反序列化的主要對象不實現接口,但是它中的一個對象實現它),它會破壞所有的反序列化。 列表不再反序列化,也不是我正在談論的對象。 序列化工作完美。

也許,而不是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;
}

編輯:此外,嘗試在您的User類上的XmlInclude批注。

[XmlInclude( typeof( Character ) )]

在對代碼進行了很長時間的討論之后,我終於放棄了使用XmlSerializer的默認行為的想法。

所有相關類現在都繼承IXmlSerializer並實現ReadXml()和WriteXml()函數。 我真的希望采取懶惰的路線,但現在我已經玩過IXmlSerializer,我意識到它真的不難,增加的靈活性非常好。

我將此屬性添加到我的List類型,然后它工作了(有同樣的問題):

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

我認為這是你的解決方案。

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;

我會嘗試使用這樣的東西。

它可能與enum的反序列化有關....因為它將它序列化為字符串值...可能無法為字符創建正確的枚舉值。 沒有測試過這個假設......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM