XmlSerializer -有一个错误反射类型

使用c# . net 2.0,我有一个组合数据类,它确实有[Serializable]属性。我正在创建一个XMLSerializer类,并将其传递给构造函数:

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

我得到一个异常说:

有错误反射类型。

在数据类内部有另一个复合对象。它是否也需要有[Serializable]属性,或者通过将它放在顶部对象上,它是否递归地应用于内部的所有对象?

267212 次浏览

看看你得到的内部异常。它将告诉您序列化哪个字段/属性有问题。

你可以用[XmlIgnore]属性将字段/属性从xml序列化中排除。

XmlSerializer没有使用[Serializable]属性,所以我怀疑这是问题所在。

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

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

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

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

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

我也认为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在公共属性上使用反射。

记住,序列化类必须有默认的(即无参数的)构造函数。如果你根本没有构造函数,那很好;但如果构造函数带有形参,则还需要添加默认形参。

还要注意XmlSerializer不能序列化抽象属性。看到我的问题在这里(我已经添加了解决方案代码)..

XML序列化和继承类型

我一直在使用NetDataSerialiser类来序列化 我的域类。NetDataContractSerializer类 . < / p >

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

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

我在在这里附近找到了一个工作。

如果你需要处理特定的属性(即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类可以很简单。

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

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

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

我遇到了类似的问题,结果是序列化器无法区分具有相同名称的两个类(一个是另一个的子类)。内部异常是这样的:

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

BaseNamespace.SubNamespace的地方。Class1是basenamspace .Class1的一个子类。

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

[XmlType("BaseNamespace.Class1")]

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

我刚刚得到了同样的错误,并发现类型IEnumerable<SomeClass>的属性是问题所在。IEnumerable似乎不能直接序列化。

相反,可以使用List<SomeClass>

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

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

.... 一些代码…

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

当我将代码更改为类中每个新Property的顺序加1时,错误就消失了。

我认为最常见的原因是:

 - the object being serialized has no parameterless constructor
- the object contains Dictionary
- the object has some public Interface members
[System.Xml.Serialization.XmlElementAttribute("strFieldName", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

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

我也有同样的问题,在我的例子中,对象有一个ReadOnlyCollection。集合必须实现Add方法才能序列化。

到目前为止,我有一个稍微不同的解决方案,所以对于任何未来的文明,这里是我的!

我已经声明了一个“time”数据类型,因为原始类型是TimeSpan,随后更改为String:

[System.Xml.Serialization.XmlElementAttribute(DataType="time", Order=3)]

然而,实际的类型是字符串

public string TimeProperty {
get {
return this.timePropertyField;
}
set {
this.timePropertyField = value;
this.RaisePropertyChanged("TimeProperty");
}
}

通过移除DateType属性,Xml可以被序列化

[System.Xml.Serialization.XmlElementAttribute(Order=3)]
public string TimeProperty {
get {
return this.timePropertyField;
}
set {
this.timePropertyField = value;
this.RaisePropertyChanged("TimeProperty");
}
}

当我创建一个具有数据类型- Type的属性时,我得到了相同的错误。在此,我得到了一个错误-有一个错误反射类型。在我的例子中,我一直在检查调试坞中每个异常的“InnerException”,并得到了特定的字段名(即Type)。解决方法如下:

    [XmlIgnore]
public Type Type { get; set; }

有时,这种类型的错误是因为你没有不带参数的类结构