C# XmlSerializer 不会序列化 IEnumerable
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9102234/
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 won't serialize IEnumerable
提问by uni
I have an invocation logger that is intended to record all method calls along with the parameters associated with the method using XmlSerializer. It works well for most of the calls, but it throws an exception for all methods that has a parameter of IEnumerabletype.
我有一个调用记录器,用于记录所有方法调用以及与使用 XmlSerializer 的方法关联的参数。它适用于大多数调用,但它会为所有具有IEnumerable类型参数的方法抛出异常。
For example, void MethodWithPlace( Place value )would be serialized, but void MethodWithPlace( IEnumerable<Place> value )would not.
例如,void MethodWithPlace( Place value )会被序列化,但void MethodWithPlace( IEnumerable<Place> value )不会。
The exception is
例外是
System.NotSupportedException: Cannot serialize interface System.Collections.Generic.IEnumerable`1[[Place, Test, Version=0.0.0.0, Culture=neutral]].
System.NotSupportedException:无法序列化接口 System.Collections.Generic.IEnumerable`1[[Place, Test, Version=0.0.0.0, Culture=neutral]]。
What should I do to make it work with those methods with IEnumerableas one of its parameters?
我应该怎么做才能使其与这些方法一起使用IEnumerable作为其参数之一?
回答by Kyle W
Basically an XmlSerializer can't serialize an interface. The solution, then, is to give it a concrete instance to serialize. Depending on how your invocation logger works, I would consider using
基本上 XmlSerializer 不能序列化接口。那么,解决方案是给它一个具体的实例来序列化。根据您的调用记录器的工作方式,我会考虑使用
var serializer = new XmlSerializer(value.GetType());
回答by Chris
I don't think you'll be able to serialize that. Try converting the IEnumerable to a List and then you will be able to serialize.
我认为您无法将其序列化。尝试将 IEnumerable 转换为 List,然后您就可以进行序列化。
回答by Sina Iravanian
回答by Herman Schoenfeld
The way you serialize an IEnumerable property is with a surrogate property
序列化 IEnumerable 属性的方式是使用代理属性
[XmlRoot]
public class Entity {
[XmlIgnore]
public IEnumerable<Foo> Foo { get; set; }
[XmlElement, Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public List<Foo> FooSurrogate { get { return Foo.ToList(); } set { Foo = value; } }
}
It's ugly, but it gets the job done. The nicer solution is to write a surrogate class (i.e. EntitySurrogate).
这很丑陋,但它完成了工作。更好的解决方案是编写一个代理类(即EntitySurrogate)。
回答by what is sleep
To be XML serializable, types which inherit from IEnumerable must have an implementation of Add(System.Object) at all levels of their inheritance hierarchy. {your class} does not implement Add(System.Object).
要进行 XML 可序列化,从 IEnumerable 继承的类型必须在其继承层次结构的所有级别都实现 Add(System.Object)。{your class} 没有实现 Add(System.Object)。
implement the Add() function, you might solve the problem
实现 Add() 函数,你可能会解决问题
回答by Maxim Eliseev
You can use DataContractSerializer
您可以使用 DataContractSerializer
using (var ms = new MemoryStream())
{
var serialiser = new DataContractSerializer(typeof (EnvironmentMetadata));
serialiser.WriteObject(ms, environmentMetadata);
var s = Encoding.ASCII.GetString(ms.ToArray());
return s;
}
回答by Everson Rafael
Maybe not the best way, but it worked for me. I created a method that makes serialization.
也许不是最好的方法,但它对我有用。我创建了一个进行序列化的方法。
Use
用
var xml = Util.ObjetoToXML(obj, null, null).OuterXml;
var xml = Util.ObjetoToXML(obj, null, null).OuterXml;
method
方法
public static XmlDocument ObjetoToXML(object obj, XmlDocument xmlDocument, XmlNode rootNode)
{
if (xmlDocument == null)
xmlDocument = new XmlDocument();
if (obj == null) return xmlDocument;
Type type = obj.GetType();
if (rootNode == null) {
rootNode = xmlDocument.CreateElement(string.Empty, type.Name, string.Empty);
xmlDocument.AppendChild(rootNode);
}
if (type.IsPrimitive || type == typeof(Decimal) || type == typeof(String) || type == typeof(DateTime))
{
// Simples types
if (obj != null)
rootNode.InnerText = obj.ToString();
}
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
{
// Genericis types
XmlNode node = null;
foreach (var item in (IEnumerable)obj)
{
if (node == null)
{
node = xmlDocument.CreateElement(string.Empty, item.GetType().Name, string.Empty);
node = rootNode.AppendChild(node);
}
ObjetoToXML(item, xmlDocument, node);
}
}
else
{
// Classes types
foreach (var propertie in obj.GetType().GetProperties())
{
XmlNode node = xmlDocument.CreateElement(string.Empty, propertie.Name, string.Empty);
node = rootNode.AppendChild(node);
var valor = propertie.GetValue(obj, null);
ObjetoToXML(valor, xmlDocument, node);
}
}
return xmlDocument;
}

