XmlSerializer – 有反映types的错误

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

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

我得到一个exception说:

有反映types的错误。

在数据类里面还有另一个复合对象。 这是否也需要具有[Serializable]属性,或者将其放置在顶层对象上,是否将其recursion应用于所有对象?

看看你正在得到的内部exception。 它会告诉你哪个字段/属性序列化有困难。

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

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

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

我有一个类似的问题,事实certificate,序列化程序无法区分我有同名的两个类(一个是另一个的子类)。 内部exception看起来像这样:

“typesBaseNamespace.Class1”和“BaseNamespace.SubNamespace.Class1”都使用名称空间“”中的XMLtypes名称“Class1”。 使用XML属性为types指定唯一的XML名称和/或名称空间。

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

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

 [XmlType("BaseNamespace.Class1")] 

注意:如果你有更多层的类,你也需要添加一个属性。

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

XML序列化和inheritancetypes

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

由于XMLSerializer是一个黑盒子,如果您想进一步debugging到序列化过程中,请检查这些链接。

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

如何:debugging到.NET XmlSerializer生成的程序集

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

我在这里find了一个工作。

我最常见的原因是:

  - the object being serialized has no parameterless constructor - the object contains Dictionary - the object has some public Interface members 

如果你需要处理特定的属性(即字典或任何类),你可以实现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包含在官方文档中,但文档声明它不适合公共使用,除此之外不提供任何信息。 这表明开发团队希望保留修改,禁用甚至完全删除这个可扩展性的权利。 但是,只要你愿意接受这种不确定性,并且处理将来可能发生的变化,就没有任何理由不能利用它。

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

…使用reflection来实现我们的自定义XmlSerializer类可能很简单。

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

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

我需要添加一个类似的属性,比自动生成的序列中的最后一个更高的顺序,这个固定了我。

我也认为Serializable属性必须位于对象上,除非我是一个完整的noob(我处于深夜编码会话的中间),以下是从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使用公共属性的reflection。

我有一个连续两个元素的顺序是相同的情况

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

….一些代码…

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

当我更改代码以便为类中的每个新Property增加一个订单时,错误就消失了。

我刚刚得到相同的错误,并发现IEnumerable<SomeClass>types的属性是问题。 看来, IEnumerable不能被直接序列化。

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

我一直在使用NetDataSerialiser类串行化我的域类。 NetDataContractSerializer类 。

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

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

//要么

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

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