web-dev-qa-db-ja.com

XmlSerializerはIEnumerableをシリアル化しません

XmlSerializerを使用して、メソッドに関連付けられたパラメーターと共にすべてのメソッド呼び出しを記録することを目的とした呼び出しロガーがあります。ほとんどの呼び出しで適切に機能しますが、IEnumerable型のパラメーターを持つすべてのメソッドに対して例外をスローします。

たとえば、void MethodWithPlace( Place value )はシリアル化されますが、void MethodWithPlace( IEnumerable<Place> value )はシリアル化されません。

例外は

System.NotSupportedException:インターフェイスSystem.Collections.Generic.IEnumerable`1 [[Place、Test、Version = 0.0.0.0、Culture = neutral]]をシリアル化できません。

パラメーターの1つとしてIEnumerableを使用してこれらのメソッドで動作させるにはどうすればよいですか?

36
uni

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)を記述することです。

29

基本的に、XmlSerializerはインターフェイスをシリアル化できません。そのための解決策は、シリアル化する具体的なインスタンスを与えることです。呼び出しロガーの機能に応じて、使用を検討します

var serializer = new XmlSerializer(value.GetType());
11
Kyle W

あなたがそれをシリアライズできるとは思わない。 IEnumerableをリストに変換すると、シリアル化できるようになります。

8
Chris

XMLシリアル化可能にするには、IEnumerableから継承する型は、継承階層のすべてのレベルでAdd(System.Object)の実装を持っている必要があります。 {あなたのクラス}はAdd(System.Object)を実装しません。

add()関数を実装すると、問題が解決する場合があります

3
what is sleep

最善の方法ではないかもしれませんが、私にとってはうまくいきました。シリアル化を行うメソッドを作成しました。

使用する

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;

    }
0
Everson Rafael