C#中集合的XML序列化

6

我有两个如下的类:

    public class Info
    { 
        [XmlAttribute] public string language;
        public int version;
        public Book book;

        public Info() { }

        public Info(string l, int v, string author, int quantity, int price)
        {
        this.language = l;
        this.version = v;
        book = new Book(author, quantity, price);
        }


    }

    public class Book
    {
            [XmlAttribute] public string author;
            public int quantity;
            public int price;
            [XmlIgnore]public int total;
            public NameValueCollection nvcollection = new NameValueCollection();

            public Book() { }

            public Book(string author, int quantity, int price)
            {
            this.author = author;
            this.quantity = quantity;
            this.price = price;
            total = quantity * price;
            nvcollection.Add(author, price.ToString());
            }

    }

我创建了一个ArrayList,它添加了两个Info类的实例,如下所示:
            FileStream fs = new FileStream("SerializedInfo.XML", FileMode.Create);

            List<Info> arrList = new List<Info>();

            XmlSerializer xs = new XmlSerializer(typeof(List<Info>));

            Info pObj = new Info("ABC", 3, "DEF", 2, 6);

            Info pObj1 = new Info("GHI", 4, "JKL", 2, 8);

            arrList.Add(pObj);
            arrList.Add(pObj1);

            xs.Serialize(fs, arrList);

            fs.Close(); 

但是当我尝试进行序列化时,会出现异常,提示信息为 "There was an error reflecting type 'System.Collections.Generic.List`1[ConsoleApplicationSerialization.Info]'."

我该如何调试此问题呢?

另外,除了namevaluecollection,我还能使用哪种类型的结构呢?

4个回答

3
NameValueCollection不直接实现ICollection接口。相反,NameValueCollection扩展了NameObjectCollectionBase。这个类实现了ICollection接口,并且Add(system.string)方法的重载在NameValueCollection类中没有实现。当你使用XMLSerializer时,XmlSerializer尝试将NameValueCollection序列化或反序列化为通用的ICollection。因此,它会寻找默认的Add(System.String)。在缺少Add(system.String)方法的情况下,会抛出异常。

尝试使用具有自定义序列化的容器类:

http://nayyeri.net/serialize-namevaluecollection

但是,我不确定您实际上要实现什么。除了书籍作者和价格之外,nvcollection还包含什么?

您打算在Book级别或更高级别的对象层次结构中使用它吗?

您可以考虑使用Dictionary而不是NameValueCollection,因为它在包含内容方面更加灵活:http://johnwsaundersiii.spaces.live.com/blog/cns!600A2BE4A82EA0A6!699.entry


1

查看内部异常。

首先,您需要使Book类可序列化。 第二件事是,NameValueCollection不能使用XmlSerializer进行序列化,因为:

“要成为XML可序列化的类型, 继承自ICollection的类型必须在其继承层次结构的所有级别上都实现Add(System.String)。 System.Collections.Specialized.NameValueCollection没有实现Add(System.String)。”

这是来自内部异常的消息。

使用以下代码片段可以正常工作:

  [Serializable]
        public class Book
        {
            [XmlAttribute]
            public string author;
            public int quantity;
            public int price;
            [XmlIgnore]
            public int total;
            //public NameValueCollection nvcollection = new NameValueCollection();
            public Book() { }
            public Book(string author, int quantity, int price)
            {
                this.author = author;
                this.quantity = quantity;
                this.price = price;
                total = quantity * price;
                //nvcollection.Add(author, price.ToString());
            }
        }

[Serializable] 属性对 XML 序列化无关紧要。 - John Saunders

0

我运行了你的代码,发现你得到的最内层异常是:

为使类型能够进行 XML 序列化,继承自 ICollection 的类型必须在其继承层次结构的所有级别上都实现 Add(System.String)。System.Collections.Specialized.NameValueCollection 未实现 Add(System.String)。

因此,XML 序列化器需要一种更简单的集合。我认为你最好的选择是在序列化之前将你的 NameValueCollection 转换为一个自定义类的列表,该类包含名称和值。


好的,如果我只是从Book类中删除NameValueCollection,那么一切都可以正常工作。 - Archie

0

更新:看起来NamedValueCollection是你真正的问题,因为它不可序列化。也许你可以使用一个可序列化字典


与标准序列化处理的类不同,使用 XML 序列化处理的类无需具备 Serializable 属性。 - Archie
我的错误。看起来你需要使用一些自定义序列化代码。 - Mark Heath

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接