反序列化包含XmlSerializer对象列表的类(c#)

问题描述:

我正在尝试使用XML序列化和更具体的XmlSerializer设置一个非常小的数据库。反序列化包含XmlSerializer对象列表的类(c#)

我的主类是以下几点:

public class XmlDB 
{ 
    [XmlIgnore] 
    public string FilePath { get; private set; } 


    public List<FooType> Foos { get; set; } 
    public List<BarType> Bars { get; set; } 
    public List<ThirdType> Thirds { get; set; } 

    private XmlDB():this(null) { } 

    public XmlDB(string strDBPath) { 
     this.FilePath = strDBPath; 
     this.Foos = new List<FooType>(); 
     this.Bars = new List<BarType>(); 
     this.Thirds = new List<ThirdType>(); 
    } 

    public static XmlDB Load(string strDBPath) { 
     using (XmlReader reader = XmlReader.Create(strDBPath)) { 
      XmlDB db = (XmlDB)new XmlSerializer(typeof(XmlDB)).Deserialize(reader); 
      db.FilePath = strDBPath; 
      return db; 
     } 
    } 

    public void SaveChanges() { 
     XmlWriterSettings settings = new XmlWriterSettings() { 
      Indent = true, 
      Encoding = Encoding.UTF8 
     }; 
     using (XmlWriter writer = XmlWriter.Create(this.FilePath, settings)) { 
      XmlSerializer ser = new XmlSerializer(typeof(XmlDB)); 
      ser.Serialize(writer, this); 
     } 
    } 
} 

我的测试方法创建一个实例,填充列表,并调用SaveChanges方法。 一切工作正常序列化和Xml输出看起来一致。

的问题发生在反序列化:未报告任何错误,但只有第一个列表的第一项处理,第一个列表的下列项目不反序列化,也不是以下列表...

如果我将Xml中的列表顺序进行混洗,它总是Xml文件中反序列化的第一个列表的第一项。

我尝试以下简单的测试,以确认(不幸的是正常工作,所有列表中填充在反序列化):

public class DBTestList 
{ 
    public List<DBTest> TestList { get; set; } 
    public List<DBTest2> TestList2 { get; set; } 

    public DBTestList() { 
     this.TestList = new List<DBTest>(); 
     this.TestList2 = new List<DBTest2>(); 
    } 
} 

public class DBTest 
{ 
    public int TestInt { get; set; } 
    public string TestStr { get; set; } 
} 

public class DBTest2 
{ 
    public int TestInt { get; set; } 
    public string TestStr { get; set; } 
} 

public void TestSerialProblem() { 
    //Init data 
    DBTestList tl = new DBTestList(); 
    tl.TestList.Add(new DBTest() { TestInt = 1, TestStr = "test11" }); 
    tl.TestList.Add(new DBTest() { TestInt = 2, TestStr = "test12" }); 
    tl.TestList2.Add(new DBTest2() { TestInt = 3, TestStr = "test21" }); 

    XmlWriterSettings settings = new XmlWriterSettings() { 
     Indent = true, 
     Encoding = Encoding.UTF8 
    }; 
    using (XmlWriter writer = XmlWriter.Create("test.db", settings)) { 
     XmlSerializer ser = new XmlSerializer(typeof(DBTestList)); 
     ser.Serialize(writer, tl); 
    } 

    using (XmlReader reader = XmlReader.Create("test.db")) { 
     DBTestList db = (DBTestList)new XmlSerializer(typeof(DBTestList)).Deserialize(reader); 
     Assert.IsTrue(db.TestList2[0].TestStr == "test21"); 
    } 
} 

我看了很多帖子关于这个问题,但没有帮助。 你有想法吗?

谢谢, 此致敬意。

编辑: 为了更详细地了解列表中使用的类,下面是一个基本的实现。 所有类型都从父一个a_SolidElement衍生,只是添加几个属性(基本值类型和/或枚举):

public abstract class a_SolidElement 
{ 
    [XmlIgnore] 
    public int Position { get; set; } 

    public virtual double Thickness { get; set; } 
    public virtual double Density { get; set; } 

    public string SupplierName { get; set; } 
    public string Name { get; set; } 
} 

public enum ElementType 
{ 
    Undefined=0, 
    TypeA, 
    TypeB 
} 

public class FooType:a_SolidElement 
{ 
    public double AdditionalData { get; set; } 

    public e_ElementType ElementType { get; set; } 
} 
+0

你可以分享(简化版本)'FooType','BarType'和'ThirdType'来重现问题吗?没有[mcve]我们只会猜测。一种可能性:三种缺失类型错误地实现了'IXmlSerializable',请参阅https://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly – dbc

+0

感谢您的评论,我添加了一个(勉强)简化列表中使用的类的版本。我试图在这些类中改变很多东西来试图缩小问题的范围,但它看起来与所有类型都是一样的。没有任何类型实现IXmlSerializable。 – nrdev

DBC实际上是正确的关于他的评论不好IXmlSerializable的实现: 在一个在我的类中,我有一个没有写入的类型的属性,在readXml方法中有问题。

我一开始并没有看到它,因为我先后删除了一些属性以查看哪一个属性导致了问题,但是这个属性仍然存在于第一个反序列化的项目中,因此即使后续项目没有它,读者仍然被第一个弄乱了。

现在非常明显,我首先感到不好意思问这个问题!

非常感谢您的帮助!