C# XmlSerializer - 有一个错误反映类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/60573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
XmlSerializer - There was an error reflecting type
提问by leora
Using C# .NET 2.0, I have a composite data class that does have the [Serializable]
attribute on it. I am creating an XMLSerializer
class and passing that into the constructor:
使用 C# .NET 2.0,我有一个复合数据类,它确实具有该[Serializable]
属性。我正在创建一个XMLSerializer
类并将其传递给构造函数:
XmlSerializer serializer = new XmlSerializer(typeof(DataClass));
I am getting an exception saying:
我收到一个异常说:
There was an error reflecting type.
存在错误反映类型。
Inside the data class there is another composite object. Does this also need to have the [Serializable]
attribute, or by having it on the top object, does it recursively apply it to all objects inside?
在数据类中还有另一个复合对象。这是否也需要具有[Serializable]
属性,或者通过将其放在顶部对象上,是否将其递归应用于内部的所有对象?
采纳答案by Lamar
Look at the inner exception that you are getting. It will tell you which field/property it is having trouble serializing.
看看你得到的内部异常。它会告诉您序列化遇到问题的字段/属性。
You can exclude fields/properties from xml serialization by decorating them with the [XmlIgnore]
attribute.
您可以通过使用[XmlIgnore]
属性修饰字段/属性来从 xml 序列化中排除它们。
XmlSerializer
does not use the [Serializable]
attribute, so I doubt that is the problem.
XmlSerializer
不使用该[Serializable]
属性,所以我怀疑这是问题所在。
回答by Phil Wright
Also note that you cannot serialize user interface controls and that any object you want to pass onto the clipboard must be serializable otherwise it cannot be passed across to other processes.
另请注意,您无法序列化用户界面控件,并且您要传递到剪贴板的任何对象都必须是可序列化的,否则无法将其传递给其他进程。
回答by Gulzar Nazim
All the objects in the serialization graph have to be serializable.
序列化图中的所有对象都必须是可序列化的。
Since XMLSerializer
is a blackbox, check these links if you want to debug further into the serialization process..
由于XMLSerializer
是一个黑盒,如果您想进一步调试序列化过程,请检查这些链接。
Changing where XmlSerializer Outputs Temporary Assemblies
回答by Darren
I too thought that the Serializable attribute had to be on the object but unless I'm being a complete noob (I am in the middle of a late night coding session) the following works from the SnippetCompiler:
我也认为 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();
}
}
}
I would imagine that the XmlSerializer is using reflection over the public properties.
我会想象 XmlSerializer 正在对公共属性使用反射。
回答by Jeremy McGee
Remember that serialized classes must have default (i.e. parameterless) constructors. If you have no constructor at all, that's fine; but if you have a constructor with a parameter, you'll need to add the default one too.
请记住,序列化类必须具有默认(即无参数)构造函数。如果您根本没有构造函数,那也没关系;但是如果你有一个带参数的构造函数,你也需要添加默认的。
回答by Rob Cooper
Also be aware that XmlSerializer
cannot serialize abstract properties.. See my question here(which I have added the solution code to)..
另请注意,XmlSerializer
无法序列化抽象属性.. 请参阅我的问题here(我已将解决方案代码添加到其中)。
回答by Rob Cooper
I have been using the NetDataSerialiser
class to serialise
my domain classes. NetDataContractSerializer Class.
我一直在使用NetDataSerialiser
该类来序列化我的域类。NetDataContractSerializer 类。
The domain classes are shared between client and server.
域类在客户端和服务器之间共享。
回答by Charlie Salts
回答by Luca
If you need to handle specific attributes (i.e. Dictionary, or any class), you can implement the IXmlSerialiableinterface, which will allow you more freedom at the cost of more verbose coding.
如果您需要处理特定的属性(即字典或任何类),您可以实现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
}
There is an interesting article, which show an elegant way to implements a sophisticated way to "extend" the XmlSerializer.
有一篇有趣的文章,它展示了一种优雅的方式来实现“扩展” XmlSerializer 的复杂方式。
The article say:
文章说:
IXmlSerializable is covered in the official documentation, but the documentation states it's not intended for public use and provides no information beyond that. This indicates that the development team wanted to reserve the right to modify, disable, or even completely remove this extensibility hook down the road. However, as long as you're willing to accept this uncertainty and deal with possible changes in the future, there's no reason whatsoever you can't take advantage of it.
IXmlSerializable 包含在官方文档中,但文档声明它不适合公共使用,并且没有提供除此之外的任何信息。这表明开发团队希望保留修改、禁用甚至完全删除此可扩展性挂钩的权利。但是,只要您愿意接受这种不确定性并应对未来可能发生的变化,就没有任何理由不能利用它。
Because this, I suggest to implement you're own IXmlSerializable
classes, in order to avoid too much complicated implementations.
正因为如此,我建议实现你自己的IXmlSerializable
类,以避免太多复杂的实现。
...it could be straightforward to implements our custom XmlSerializer
class using reflection.
...XmlSerializer
使用反射实现我们的自定义类可能很简单。
回答by LepardUK
I recently got this in a web reference partial class when adding a new property. The auto generated class was adding the following attributes.
我最近在添加新属性时在 Web 参考部分类中得到了这个。自动生成的类添加了以下属性。
[System.Xml.Serialization.XmlElementAttribute(Order = XX)]
I needed to add a similar attribute with an order one higher than the last in the auto generated sequence and this fixed it for me.
我需要添加一个类似的属性,其顺序比自动生成的序列中的最后一个高,这为我修复了它。