XmlSerializer不会序列化IEnumerable

时间:2012-02-01 19:47:45

标签: c# xml-serialization xmlserializer

我有一个调用记录器,用于记录所有方法调用以及与使用XmlSerializer的方法相关的参数。它适用于大多数调用,但它会为参数为IEnumerable类型的所有方法抛出异常。

例如,void MethodWithPlace( Place value )将被序列化,但void MethodWithPlace( IEnumerable<Place> value )不会。

例外是

  

System.NotSupportedException:无法序列化接口   System.Collections.Generic.IEnumerable`1 [广场,   测试,版本= 0.0.0.0,文化=中立]]。

我应该怎么做才能使IEnumerable作为参数之一使用这些方法?

7 个答案:

答案 0 :(得分:27)

序列化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; } }
}

这很丑陋,但它完成了工作。更好的解决方案是编写代理类(即EntitySurrogate)。

答案 1 :(得分:10)

基本上,XmlSerializer无法序列化接口。然后,解决方案是给它一个序列化的具体实例。根据您的调用记录器的工作方式,我会考虑使用

var serializer = new XmlSerializer(value.GetType());

答案 2 :(得分:8)

我认为你无法将其序列化。尝试将IEnumerable转换为List,然后就可以序列化了。

答案 3 :(得分:3)

要成为XML可序列化,从IEnumerable继承的类型必须在其继承层次结构的所有级别都具有Add(System.Object)的实现。 {your class}没有实现Add(System.Object)。

实现Add()函数,你可以解决问题

答案 4 :(得分:0)

也许不是最好的方式,但它对我有用。 我创建了一个进行序列化的方法。

使用

var xml = Util.ObjetoToXML(obj,null,null).OuterXml;

方法

        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;

    }

答案 5 :(得分:-1)

XmlSerializer不支持此功能。请尝试使用YAXLib进行此类序列化。

答案 6 :(得分:-1)

您可以使用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;
        }