XmlSerializer - 反映类型时出错

c# .net xml serialization .net-2.0

216105 观看

16回复

39595 作者的声誉

使用C#.NET 2.0,我有一个复合数据类,它具有该[Serializable]属性。我正在创建一个XMLSerializer类并将其传递给构造函数:

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

我得到一个例外说:

有一个反映类型的错误。

在数据类内部还有另一个复合对象。这是否还需要具有该[Serializable]属性,或者将其置于顶层对象上,是否以递归方式将其应用于内部的所有对象?

作者: leora 的来源 发布者: 2008 年 9 月 13 日

回应 (16)


399

7546 作者的声誉

决定

看看你得到的内在异常。它将告诉您序列化时遇到问题的字段/属性。

您可以通过使用[XmlIgnore]属性进行装饰来从xml序列化中排除字段/ 属性。

我不认为XmlSerializer使用该[Serializable]属性,所以我怀疑这是问题所在。

作者: Lamar 发布者: 13.09.2008 02:53

0

17510 作者的声誉

另请注意,您无法序列化用户界面控件,并且您要传递到剪贴板的任何对象必须是可序列化的,否则无法传递给其他进程。

作者: Phil Wright 发布者: 13.09.2008 02:55

5

46172 作者的声誉

序列化图中的所有对象都必须是可序列化的。

由于XMLSerializer是黑盒子,如果要进一步调试序列化过程,请检查这些链接。

更改XmlSerializer输出临时程序集的位置

HOW TO:调试到.NET XmlSerializer生成的程序集

作者: Gulzar Nazim 发布者: 13.09.2008 03:05

2

793 作者的声誉

我也认为Serializable属性必须在对象上,但除非我是一个完整的菜鸟(我正处于深夜编码会话中),否则以下是SnippetCompiler的工作原理:

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

public class Inner
{
    private string _AnotherStringProperty;
    public string AnotherStringProperty 
    { 
      get { return _AnotherStringProperty; } 
      set { _AnotherStringProperty = value; } 
    }
}

public class DataClass
{
    private string _StringProperty;
    public string StringProperty 
    { 
       get { return _StringProperty; } 
       set{ _StringProperty = value; } 
    }

    private Inner _InnerObject;
    public Inner InnerObject 
    { 
       get { return _InnerObject; } 
       set { _InnerObject = value; } 
    }
}

public class MyClass
{

    public static void Main()
    {
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(DataClass));
            TextWriter writer = new StreamWriter(@"c:\tmp\dataClass.xml");
            DataClass clazz = new DataClass();
            Inner inner = new Inner();
            inner.AnotherStringProperty = "Foo2";
            clazz.InnerObject = inner;
            clazz.StringProperty = "foo";
            serializer.Serialize(writer, clazz);
        }
        finally
        {
            Console.Write("Press any key to continue...");
            Console.ReadKey();
        }
    }

}

我想,XmlSerializer正在使用公共属性的反射。

作者: Darren 发布者: 13.09.2008 03:23

108

19132 作者的声誉

请记住,序列化类必须具有默认(即无参数)构造函数。如果你根本没有构造函数,那很好; 但是如果你有一个带参数的构造函数,你也需要添加默认值。

作者: Jeremy McGee 发布者: 13.09.2008 04:23

7

21227 作者的声誉

另外请注意,XmlSerializer不能序列化抽象属性..请在这里查看我的问题(我已经添加了解决方案代码)..

XML序列化和继承类型

作者: Rob Cooper 发布者: 13.09.2008 05:31

0

0 作者的声誉

我一直在使用NetDataSerialiser该类来序列化我的域类。NetDataContractSerializer类

域类在客户端和服务器之间共享。

作者: peterka 发布者: 16.09.2008 01:14

4

9279 作者的声誉

我发现.Net 2.0中的Dictionary类不能使用XML进行序列化,但在使用二进制序列化时序列化很好。

我在这里找到了一份工作。

作者: Charlie Salts 发布者: 02.07.2009 07:32

5

8026 作者的声誉

如果您需要处理特定属性(即Dictionary或任何类),您可以实现IXmlSerialiable接口,这将允许您以更冗长的编码为代价获得更多自由。

public class NetService : IXmlSerializable
{
    #region Data

        public string Identifier = String.Empty;

        public string Name = String.Empty;

        public IPAddress Address = IPAddress.None;
        public int Port = 7777;

    #endregion

    #region IXmlSerializable Implementation

        public XmlSchema GetSchema() { return (null); }

        public void ReadXml(XmlReader reader)
        {
            // Attributes
            Identifier = reader[XML_IDENTIFIER];
            if (Int32.TryParse(reader[XML_NETWORK_PORT], out Port) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_PORT);
            if (IPAddress.TryParse(reader[XML_NETWORK_ADDR], out Address) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_ADDR);
        }

        public void WriteXml(XmlWriter writer)
        {
            // Attributes
            writer.WriteAttributeString(XML_IDENTIFIER, Identifier);
            writer.WriteAttributeString(XML_NETWORK_ADDR, Address.ToString());
            writer.WriteAttributeString(XML_NETWORK_PORT, Port.ToString());
        }

        private const string XML_IDENTIFIER = "Id";

        private const string XML_NETWORK_ADDR = "Address";

        private const string XML_NETWORK_PORT = "Port";

    #endregion
}

有一篇有趣的文章,展示了一种实现“扩展”XmlSerializer的复杂方法的优雅方法。


文章说:

IXmlSerializable包含在官方文档中,但文档声明它不是供公众使用的,除此之外不提供任何信息。这表明开发团队希望保留修改,禁用甚至完全删除此可扩展性挂钩的权利。但是,只要你愿意接受这种不确定性并处理未来可能发生的变化,就没有任何理由你无法利用它。

因为这个,我建议你实现自己的IXmlSerializable类,以避免过多的复杂实现。

... XmlSerializer使用反射实现我们的自定义类可能很简单。

作者: Luca 发布者: 26.04.2010 06:34

3

851 作者的声誉

我最近在添加新属性时在Web引用分部类中得到了这个。自动生成的类正在添加以下属性。

    [System.Xml.Serialization.XmlElementAttribute(Order = XX)]

我需要添加一个类似的属性,其顺序比自动生成的序列中的最后一个高一个,这为我修复了它。

作者: LepardUK 发布者: 17.12.2010 02:15

24

544 作者的声誉

我遇到了类似的问题,结果发现序列化程序无法区分我使用相同名称的两个类(一个是另一个类的子类)。内部异常看起来像这样:

'Types BaseNamespace.Class1'和'BaseNamespace.SubNamespace.Class1'都使用来自命名空间''的XML类型名称'Class1'。使用XML属性为类型指定唯一的XML名称和/或命名空间。

其中BaseNamespace.SubNamespace.Class1是BaseNamespace.Class1的子类。

我需要做的是为其中一个类添加一个属性(我添加到基类):

[XmlType("BaseNamespace.Class1")]

注意:如果您有更多层类,则还需要为它们添加属性。

作者: Dennis Calla 发布者: 16.09.2011 09:51

2

1273 作者的声誉

我刚刚得到同样的错误,发现类型的属性IEnumerable<SomeClass>是问题。看来IEnumerable无法直接序列化。

相反,人们可以使用List<SomeClass>

作者: jkokorian 发布者: 12.01.2012 12:59

1

11 作者的声誉

我有一种情况,订单对于连续的两个元素是相同的

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "SeriousInjuryFlag")]

....一些代码......

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "AccidentFlag")]

当我更改代码以便为类中的每个新属性增加一个顺序时,错误就消失了。

作者: Jeremy Brown 发布者: 17.12.2012 10:22

6

2668 作者的声誉

我最常见的原因:

 - the object being serialized has no parameterless constructor
 - the object contains Dictionary
 - the object has some public Interface members
作者: Stefan Michev 发布者: 22.02.2014 12:29

0

354 作者的声誉

[System.Xml.Serialization.XmlElementAttribute(“strFieldName”,Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

//要么

[XmlIgnore] string [] strFielsName {get; set;}

作者: Kiran.Bakwad 发布者: 16.02.2017 11:48

0

8 作者的声誉

我有同样的问题,在我的情况下,对象有一个ReadOnlyCollection。集合必须实现Add方法才能进行序列化。

作者: Curious Dev 发布者: 26.05.2017 01:19
32x32