C# 列表的XML(反)序列化

C# 列表的XML(反)序列化,c#,xml-serialization,xmlserializer,C#,Xml Serialization,Xmlserializer,目前,我正在尝试将我的一些类序列化并反序列化为XML。单向(List->XML)可以很好地工作(参见下面的示例)。另一种方法无法正常工作。 我不想反序列化的类本身包含另一个类的另一个列表。这也正确地存在于XML文件中。但是,当我反序列化类时,它将不起作用 在下面的示例中,这意味着类Foo使用其条列表正确序列化。但是当我反序列化XML文件时,只有FooString和其他属性被正确序列化。酒吧列表每次都是空的。调试器也不会在任何时候到达那里 有人能告诉我我做错了什么吗 提前谢谢 主要对象如下所示:

目前,我正在尝试将我的一些类序列化并反序列化为XML。单向(List->XML)可以很好地工作(参见下面的示例)。另一种方法无法正常工作。 我不想反序列化的类本身包含另一个类的另一个列表。这也正确地存在于XML文件中。但是,当我反序列化类时,它将不起作用

在下面的示例中,这意味着类Foo使用其条列表正确序列化。但是当我反序列化XML文件时,只有FooString和其他属性被正确序列化。酒吧列表每次都是空的。调试器也不会在任何时候到达那里

有人能告诉我我做错了什么吗

提前谢谢

主要对象如下所示:

[XmlInclude(typeof (Bar))]
[XmlRoot(ElementName = "Foo")]
public class Foo()  : IFooInterface
{
    [XmlElement("FooString")]
    public string FooString
    {
        // For simplifaction auto proerty, normally with
        // backing field
        get;
        set;
    }

    // Some other properties for the xml
    // ...

    // Dirty Hack to serialize the List, because an Interface could not be serialized
    // I've already tried to remove this tag, to replace it with [XmlElement("BarList")], but nothing works
    [XmlArray("BarList")]
    [XmlArrayItem(ElementName = "Bar", Type = typeof(Bar))]
    public List<Bar> XmlBarList
    {
        get
        {
            return this.BarList.Select(bar => bar as Bar).ToList();
        }
        set
        {
            this.BarList = new ObservableCollection<IBarInterface>(value);
        }
    }

    private ObservableCollection<IBarInterface> barList;

    [XmlIgnore]
    public ObservableCollection<IBarInterface> BarList
    {
        get
        {
            return this.barList;
        }
        set
        {
            // For simplification removed Notification Proerties
            this.barList = value;
        }
    }
}
[XmlType("Bar")]
public class Bar : IBarInterface
{
    [XmlElement("BarString")]
    public string BarString
    {
        get;
        set;
    }

    // Some other properties for the xml 
    // ...
}
<ArrayOfFoo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Foo>
    <BarList>
      <Bar>
        <BarString>Hello Bar!</BarString>
      </Bar>
    </BarList>
    <FooString>Hello Foo!</FooString>
  </Foo>
</ArrayOfFoo>
public interface IFooInterface
{
    ObservableCollection<IBarInterface> BarList { get; }
}
[XmlInclude(typeof(Bar))]
[XmlRoot(ElementName ="Foo")]
public class Foo : IFooInterface
{
    ObservableCollection<IBarInterface> barList;

    [XmlElement(ElementName ="BarList")]
    public ObservableCollection<Bar> XmlBarList
    {
        get
        {
            // Creates an temporary Object, so it won't work
            return this.BarList.Select(bar => bar as Bar).ToList();
        }
        set
        {
             this.BarList = new ObservableCollection<IBarInterface>(value);
        }
    }

    // Won't work out of the box with XmlSerializer
    // so I Ignore it
    [XmlIgnore]
    ObservableCollection<IBarInterface> BarList
    {
        get
        {
            return this.barList;
        }
        set
        {
            this.barList = value;
        }
    }
}
public interface IBarInterface
{
    string BarString { get; }
}
[XmlRoot(ElementName ="Bar")]
public class Bar : IBarInterface
{
    string BarString;

    [XmlElement(ElementName = "BarString")]
    string BarString
    {
        get
        {
            return this.bar;
        }
        set
        {
            this.bar = value;
        }
    }
}
对类进行(反)序列化的类:

public class FooBarProvider()
{
    // Won't work
    // the BarList of any Foo item is everytime
    // empty. 
    public List<Foo> Load()
    {
        var reader = new StreamReader("PathToTheXml.xml");
        var serializer = new XmlSerializer(typeof(List<Foo>));
        var list = (List<Foo>)serializer.Deserialize(reader);
    }

    // Works
    public void Save(List<Foo> fooList)
    {
       var serializer = new XmlSerializer(typeof(List<Foo>));
       var writer = new StreamWriter("PathToTheXml.xml");
       serializer.Serialize(writer, fooList);
       writer.Close();
    }
}
public类FooBarProvider()
{
//行不通
//任何Foo项的BarList都是
//空的。
公共列表加载()
{
var reader=newstreamreader(“PathToTheXml.xml”);
var serializer=newxmlserializer(typeof(List));
变量列表=(列表)序列化程序。反序列化(读取器);
}
//工作
公共作废保存(列表傻瓜)
{
var serializer=newxmlserializer(typeof(List));
var writer=newstreamwriter(“PathToTheXml.xml”);
序列化器。序列化(编写器、傻瓜);
writer.Close();
}
}
生成的XML文件:

[XmlInclude(typeof (Bar))]
[XmlRoot(ElementName = "Foo")]
public class Foo()  : IFooInterface
{
    [XmlElement("FooString")]
    public string FooString
    {
        // For simplifaction auto proerty, normally with
        // backing field
        get;
        set;
    }

    // Some other properties for the xml
    // ...

    // Dirty Hack to serialize the List, because an Interface could not be serialized
    // I've already tried to remove this tag, to replace it with [XmlElement("BarList")], but nothing works
    [XmlArray("BarList")]
    [XmlArrayItem(ElementName = "Bar", Type = typeof(Bar))]
    public List<Bar> XmlBarList
    {
        get
        {
            return this.BarList.Select(bar => bar as Bar).ToList();
        }
        set
        {
            this.BarList = new ObservableCollection<IBarInterface>(value);
        }
    }

    private ObservableCollection<IBarInterface> barList;

    [XmlIgnore]
    public ObservableCollection<IBarInterface> BarList
    {
        get
        {
            return this.barList;
        }
        set
        {
            // For simplification removed Notification Proerties
            this.barList = value;
        }
    }
}
[XmlType("Bar")]
public class Bar : IBarInterface
{
    [XmlElement("BarString")]
    public string BarString
    {
        get;
        set;
    }

    // Some other properties for the xml 
    // ...
}
<ArrayOfFoo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Foo>
    <BarList>
      <Bar>
        <BarString>Hello Bar!</BarString>
      </Bar>
    </BarList>
    <FooString>Hello Foo!</FooString>
  </Foo>
</ArrayOfFoo>
public interface IFooInterface
{
    ObservableCollection<IBarInterface> BarList { get; }
}
[XmlInclude(typeof(Bar))]
[XmlRoot(ElementName ="Foo")]
public class Foo : IFooInterface
{
    ObservableCollection<IBarInterface> barList;

    [XmlElement(ElementName ="BarList")]
    public ObservableCollection<Bar> XmlBarList
    {
        get
        {
            // Creates an temporary Object, so it won't work
            return this.BarList.Select(bar => bar as Bar).ToList();
        }
        set
        {
             this.BarList = new ObservableCollection<IBarInterface>(value);
        }
    }

    // Won't work out of the box with XmlSerializer
    // so I Ignore it
    [XmlIgnore]
    ObservableCollection<IBarInterface> BarList
    {
        get
        {
            return this.barList;
        }
        set
        {
            this.barList = value;
        }
    }
}
public interface IBarInterface
{
    string BarString { get; }
}
[XmlRoot(ElementName ="Bar")]
public class Bar : IBarInterface
{
    string BarString;

    [XmlElement(ElementName = "BarString")]
    string BarString
    {
        get
        {
            return this.bar;
        }
        set
        {
            this.bar = value;
        }
    }
}

你好吧!
喂,福!

不要使用XmlArray。它会创建一组额外的节点。改用XmlElement

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {

            ArrayOfFoo aof = new ArrayOfFoo() {
                foo = new Foo() {
                     FooString = "Hello Foo!",
                     barList = new List<BarList>() {
                        new BarList() {
                          bar = new Bar() {
                              barString = "Hello Bar!"
                          }
                        }
                     }
                }
            };

            XmlSerializer serializer = new XmlSerializer(typeof(ArrayOfFoo));

            StreamWriter writer = new StreamWriter(FILENAME);
            serializer.Serialize(writer, aof);
            writer.Flush();
            writer.Close();
            writer.Dispose();

            XmlSerializer xs = new XmlSerializer(typeof(ArrayOfFoo));
            XmlTextReader reader = new XmlTextReader(FILENAME);
            ArrayOfFoo newAof = (ArrayOfFoo)xs.Deserialize(reader);
        }
    }
    [XmlRoot(ElementName = "ArrayOfFoo")]
    public class ArrayOfFoo
    {
        [XmlElement("Foo")]
        public Foo foo { get; set; }
    }

     [XmlRoot(ElementName = "Foo")]
    public class Foo
    {
        [XmlElement("FooString")]
        public string FooString { get; set; }


        [XmlElement("BarList")]
        public List<BarList> barList { get; set; }

    }


    [XmlRoot(ElementName = "BarList")]
    public class BarList
    {
        [XmlElement("Bar")]
        public Bar bar { get; set; }
    }


    [XmlRoot(ElementName = "Bar")]
    public class Bar
    {
        [XmlElement("BarString")]
        public string barString { get; set; }
    }
    [XmlRoot(ElementName = "BarString")]
    public class BarString
    {
        [XmlText]
        public string value { get; set; }
    }​
}
​
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.IO;
使用System.Xml;
使用System.Xml.Serialization;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
ArrayOfFoo aof=新的ArrayOfFoo(){
foo=新foo(){
FooString=“你好,Foo!”,
barList=新列表(){
新酒吧名单(){
bar=新的bar(){
barString=“你好,酒吧!”
}
}
}
}
};
XmlSerializer serializer=新的XmlSerializer(typeof(ArrayOfFoo));
StreamWriter writer=新的StreamWriter(文件名);
serializer.Serialize(writer,aof);
writer.Flush();
writer.Close();
writer.Dispose();
XmlSerializer xs=新的XmlSerializer(typeof(ArrayOfFoo));
XmlTextReader=新的XmlTextReader(文件名);
ArrayOfFoo newAof=(ArrayOfFoo)xs.反序列化(读卡器);
}
}
[XmlRoot(ElementName=“ArrayOfFoo”)]
公共类ArrayOfFoo
{
[XmlElement(“Foo”)]
公共Foo Foo{get;set;}
}
[XmlRoot(ElementName=“Foo”)]
公开课Foo
{
[xmlement(“FooString”)]
公共字符串FooString{get;set;}
[XmlElement(“BarList”)]
公共列表barList{get;set;}
}
[XmlRoot(ElementName=“BarList”)]
公共类酒吧列表
{
[XmlElement(“条”)]
公共条{get;set;}
}
[XmlRoot(ElementName=“Bar”)]
公共类酒吧
{
[XmlElement(“BarString”)]
公共字符串barString{get;set;}
}
[XmlRoot(ElementName=“BarString”)]
公共类条字符串
{
[XmlText]
公共字符串值{get;set;}
}​
}
​
哦,该死

我明白我的错误了

通过我对接口对象进行串行化的肮脏“黑客”,它将创建一个临时对象。XmlSerializer获取临时对象并将数据存储在那里

是否有其他方法可以序列化和反序列化接口?在Foo类中,我知道它是bar的一个实例。但是这个接口迫使我实现一个IBarInterface列表

用于
Foo的接口

[XmlInclude(typeof (Bar))]
[XmlRoot(ElementName = "Foo")]
public class Foo()  : IFooInterface
{
    [XmlElement("FooString")]
    public string FooString
    {
        // For simplifaction auto proerty, normally with
        // backing field
        get;
        set;
    }

    // Some other properties for the xml
    // ...

    // Dirty Hack to serialize the List, because an Interface could not be serialized
    // I've already tried to remove this tag, to replace it with [XmlElement("BarList")], but nothing works
    [XmlArray("BarList")]
    [XmlArrayItem(ElementName = "Bar", Type = typeof(Bar))]
    public List<Bar> XmlBarList
    {
        get
        {
            return this.BarList.Select(bar => bar as Bar).ToList();
        }
        set
        {
            this.BarList = new ObservableCollection<IBarInterface>(value);
        }
    }

    private ObservableCollection<IBarInterface> barList;

    [XmlIgnore]
    public ObservableCollection<IBarInterface> BarList
    {
        get
        {
            return this.barList;
        }
        set
        {
            // For simplification removed Notification Proerties
            this.barList = value;
        }
    }
}
[XmlType("Bar")]
public class Bar : IBarInterface
{
    [XmlElement("BarString")]
    public string BarString
    {
        get;
        set;
    }

    // Some other properties for the xml 
    // ...
}
<ArrayOfFoo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Foo>
    <BarList>
      <Bar>
        <BarString>Hello Bar!</BarString>
      </Bar>
    </BarList>
    <FooString>Hello Foo!</FooString>
  </Foo>
</ArrayOfFoo>
public interface IFooInterface
{
    ObservableCollection<IBarInterface> BarList { get; }
}
[XmlInclude(typeof(Bar))]
[XmlRoot(ElementName ="Foo")]
public class Foo : IFooInterface
{
    ObservableCollection<IBarInterface> barList;

    [XmlElement(ElementName ="BarList")]
    public ObservableCollection<Bar> XmlBarList
    {
        get
        {
            // Creates an temporary Object, so it won't work
            return this.BarList.Select(bar => bar as Bar).ToList();
        }
        set
        {
             this.BarList = new ObservableCollection<IBarInterface>(value);
        }
    }

    // Won't work out of the box with XmlSerializer
    // so I Ignore it
    [XmlIgnore]
    ObservableCollection<IBarInterface> BarList
    {
        get
        {
            return this.barList;
        }
        set
        {
            this.barList = value;
        }
    }
}
public interface IBarInterface
{
    string BarString { get; }
}
[XmlRoot(ElementName ="Bar")]
public class Bar : IBarInterface
{
    string BarString;

    [XmlElement(ElementName = "BarString")]
    string BarString
    {
        get
        {
            return this.bar;
        }
        set
        {
            this.bar = value;
        }
    }
}
条形码的界面:

[XmlInclude(typeof (Bar))]
[XmlRoot(ElementName = "Foo")]
public class Foo()  : IFooInterface
{
    [XmlElement("FooString")]
    public string FooString
    {
        // For simplifaction auto proerty, normally with
        // backing field
        get;
        set;
    }

    // Some other properties for the xml
    // ...

    // Dirty Hack to serialize the List, because an Interface could not be serialized
    // I've already tried to remove this tag, to replace it with [XmlElement("BarList")], but nothing works
    [XmlArray("BarList")]
    [XmlArrayItem(ElementName = "Bar", Type = typeof(Bar))]
    public List<Bar> XmlBarList
    {
        get
        {
            return this.BarList.Select(bar => bar as Bar).ToList();
        }
        set
        {
            this.BarList = new ObservableCollection<IBarInterface>(value);
        }
    }

    private ObservableCollection<IBarInterface> barList;

    [XmlIgnore]
    public ObservableCollection<IBarInterface> BarList
    {
        get
        {
            return this.barList;
        }
        set
        {
            // For simplification removed Notification Proerties
            this.barList = value;
        }
    }
}
[XmlType("Bar")]
public class Bar : IBarInterface
{
    [XmlElement("BarString")]
    public string BarString
    {
        get;
        set;
    }

    // Some other properties for the xml 
    // ...
}
<ArrayOfFoo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Foo>
    <BarList>
      <Bar>
        <BarString>Hello Bar!</BarString>
      </Bar>
    </BarList>
    <FooString>Hello Foo!</FooString>
  </Foo>
</ArrayOfFoo>
public interface IFooInterface
{
    ObservableCollection<IBarInterface> BarList { get; }
}
[XmlInclude(typeof(Bar))]
[XmlRoot(ElementName ="Foo")]
public class Foo : IFooInterface
{
    ObservableCollection<IBarInterface> barList;

    [XmlElement(ElementName ="BarList")]
    public ObservableCollection<Bar> XmlBarList
    {
        get
        {
            // Creates an temporary Object, so it won't work
            return this.BarList.Select(bar => bar as Bar).ToList();
        }
        set
        {
             this.BarList = new ObservableCollection<IBarInterface>(value);
        }
    }

    // Won't work out of the box with XmlSerializer
    // so I Ignore it
    [XmlIgnore]
    ObservableCollection<IBarInterface> BarList
    {
        get
        {
            return this.barList;
        }
        set
        {
            this.barList = value;
        }
    }
}
public interface IBarInterface
{
    string BarString { get; }
}
[XmlRoot(ElementName ="Bar")]
public class Bar : IBarInterface
{
    string BarString;

    [XmlElement(ElementName = "BarString")]
    string BarString
    {
        get
        {
            return this.bar;
        }
        set
        {
            this.bar = value;
        }
    }
}
IBarInterface的实现:

[XmlInclude(typeof (Bar))]
[XmlRoot(ElementName = "Foo")]
public class Foo()  : IFooInterface
{
    [XmlElement("FooString")]
    public string FooString
    {
        // For simplifaction auto proerty, normally with
        // backing field
        get;
        set;
    }

    // Some other properties for the xml
    // ...

    // Dirty Hack to serialize the List, because an Interface could not be serialized
    // I've already tried to remove this tag, to replace it with [XmlElement("BarList")], but nothing works
    [XmlArray("BarList")]
    [XmlArrayItem(ElementName = "Bar", Type = typeof(Bar))]
    public List<Bar> XmlBarList
    {
        get
        {
            return this.BarList.Select(bar => bar as Bar).ToList();
        }
        set
        {
            this.BarList = new ObservableCollection<IBarInterface>(value);
        }
    }

    private ObservableCollection<IBarInterface> barList;

    [XmlIgnore]
    public ObservableCollection<IBarInterface> BarList
    {
        get
        {
            return this.barList;
        }
        set
        {
            // For simplification removed Notification Proerties
            this.barList = value;
        }
    }
}
[XmlType("Bar")]
public class Bar : IBarInterface
{
    [XmlElement("BarString")]
    public string BarString
    {
        get;
        set;
    }

    // Some other properties for the xml 
    // ...
}
<ArrayOfFoo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Foo>
    <BarList>
      <Bar>
        <BarString>Hello Bar!</BarString>
      </Bar>
    </BarList>
    <FooString>Hello Foo!</FooString>
  </Foo>
</ArrayOfFoo>
public interface IFooInterface
{
    ObservableCollection<IBarInterface> BarList { get; }
}
[XmlInclude(typeof(Bar))]
[XmlRoot(ElementName ="Foo")]
public class Foo : IFooInterface
{
    ObservableCollection<IBarInterface> barList;

    [XmlElement(ElementName ="BarList")]
    public ObservableCollection<Bar> XmlBarList
    {
        get
        {
            // Creates an temporary Object, so it won't work
            return this.BarList.Select(bar => bar as Bar).ToList();
        }
        set
        {
             this.BarList = new ObservableCollection<IBarInterface>(value);
        }
    }

    // Won't work out of the box with XmlSerializer
    // so I Ignore it
    [XmlIgnore]
    ObservableCollection<IBarInterface> BarList
    {
        get
        {
            return this.barList;
        }
        set
        {
            this.barList = value;
        }
    }
}
public interface IBarInterface
{
    string BarString { get; }
}
[XmlRoot(ElementName ="Bar")]
public class Bar : IBarInterface
{
    string BarString;

    [XmlElement(ElementName = "BarString")]
    string BarString
    {
        get
        {
            return this.bar;
        }
        set
        {
            this.bar = value;
        }
    }
}

嗨,谢谢你的回复。但这也不起作用。我试过了。我还尝试删除标签,让它自动决定。但是我做的每件事——这都行不通:/你有别的方法吗?你真的不需要ArrayofFoo和Foo。它们可以组合成一个类。此外,BarList和Bar也可以组合成一个类。