318

C#.NET 2.0を使用して、私は持っている複合データクラスを持っています[Serializable]その上に属性。私は作成していますXMLSerializerクラスとそれをコンストラクタに渡す:

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

私は例外を言っているのですが:

型を反映するエラーがありました。

データクラス内には、もう1つの複合オブジェクトがあります。これはまた持っている必要がありますか[Serializable]属性、またはそれを一番上のオブジェクトに持つことで、それを内部のすべてのオブジェクトに再帰的に適用しますか。

16 답변


394

あなたが得ている内部の例外を見てください。どのフィールド/プロパティがシリアル化に問題があるのかがわかります。

あなたはそれらをで飾ることによってxml直列化からフィールド/プロパティを除外することができます。[XmlIgnore]属性。

私はそうは思わないXmlSerializerを使用します[Serializable]属性なので、それが問題ではないと思います。


  • 私のオブジェクトはUriフィールドを持っていたため、この例外が発生しました。 Uriクラスには、パラメータなしのコンストラクタはありません。先端をありがとう。 - ford
  • グーグル検索でこれに遭遇した - 私の特別な問題は私の"にシリアル化された"にプロパティがあることでした。クラスとしてIList必要なときList。 - Paul Aldred-Bann
  • 「内部例外」をどのように見ていますか。 - David
  • または、' @ exception'を追加してください。時計に - arolson101
  • ありがとう、この答えは私を助けてくれました。私は最初内部の例外を見て、そしてちょうどメインクラスの言及を見ました。しかし、私は私が私自身がその過敏性の過小評価を掘り下げることができることに気づいた、そして最終的には5つのレベルが下がると、私はその問題を発見した。衝突しているクラスがありました。ありがとう。 - Louis van Tonder

108

直列化されたクラスにはデフォルトの(つまりパラメータのない)コンストラクタが必要です。あなたがまったくコンストラクタを持っていなければ、それで問題ありません。ただし、パラメータを持つコンストラクタがある場合は、デフォルトのものも追加する必要があります。


  • 念押し有難う!私はこれがほとんど説明のないランタイムエラーであることを嫌います。 - Jared Updike
  • 私はこの過ちを何度も繰り返し続けています。パラメータのないコンストラクタを使うように私に思い出させてくれてありがとう^^ - aZtraL-EnForceR

22

私は同じような問題を抱えていた、そしてそれはシリアライザが私が同じ名前を持っていた2つのクラスを区別することができなかったことがわかった(1つは他のサブクラスだった)。内部例外は次のようになりました。

'Types BaseNamespace.Class1'と 'BaseNamespace.SubNamespace.Class1'はどちらも、名前空間 ''からのXML型名 'Class1'を使用します。 XML属性を使用して、タイプに固有のXML名または名前空間、あるいはその両方を指定します。

BaseNamespace.SubNamespace.Class1はBaseNamespace.Class1のサブクラスです。

必要なのは、クラスの1つに属性を追加することです(私は基本クラスに追加しました)。

[XmlType("BaseNamespace.Class1")]

注:クラスの層がもっとある場合は、それらに属性を追加する必要があります。


  • これで問題は解決しました、ありがとう、+ 1。私はいくつかのProcessor *オブジェクトについても同様の設定をしました。それぞれのオブジェクトはConfig内部クラスを持ちます。ランタイムはSomeNS.Processor1.ConfigとSomeNS.Processor2.Configを区別できませんでした。 - damix911

7

また注意してくださいXmlSerializer抽象プロパティをシリアル化できません。私の質問を参照してください。ここに(私はにソリューションコードを追加しました)..

XMLシリアル化と継承型


6

私による最も一般的な理由:

 - the object being serialized has no parameterless constructor
 - the object contains Dictionary
 - the object has some public Interface members


5

直列化グラフ内のすべてのオブジェクトは直列化可能でなければなりません。

からXMLSerializerブラックボックスです。シリアル化プロセスをさらにデバッグする場合は、これらのリンクを確認してください。

XmlSerializerが一時的なアセンブリを出力する場所を変更する

HOW TO:.NET XmlSerializer生成アセンブリへのデバッグ


5

もしあなたが特定の属性(すなわち辞書、または任意のクラス)を扱う必要があるならば、あなたは以下を実装することができます。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リフレクションを使用したクラス


4

.NET 2.0のDictionaryクラスはXMLを使用してシリアライズすることはできませんが、バイナリシリアライゼーションを使用するとうまくシリアライズされます。

私は回避策を見つけましたここに


3

私は最近、新しいプロパティを追加するときにWeb参照部分クラスでこれを得ました。自動生成されたクラスは以下の属性を追加していました。

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

私は自動生成されたシーケンスの最後のものより1つ上のオーダーで同様の属性を追加する必要があり、これは私のためにそれを修正しました。


2

私も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がパブリックプロパティに対してリフレクションを使用していると思います。


2

私はちょうど同じエラーを得たとタイプのプロパティがIEnumerable<SomeClass>問題でした。どうやらIEnumerable直接シリアル化することはできません。


1

2つの要素が順番に並んでいるのにOrderが同じという状況がありました

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

....いくつかのコード...

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

クラス内の新しいPropertyごとに順番を1つ増やすようにコードを変更したところ、エラーは消えました。


0

また、ユーザーインターフェイスコントロールをシリアル化することはできません。また、クリップボードに渡すオブジェクトはシリアル化可能である必要があります。そうしないと他のプロセスに渡すことができません。


0

私は使っていますNetDataSerialiser直列化するクラス 私のドメインクラスNetDataContractSerializerクラス

ドメインクラスはクライアントとサーバー間で共有されます。


0

[System.Xml.Serialization.XmlElementAttribute( "strFieldName"、Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

//または

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


0

私は同じ問題を抱えていました、そして私のケースではオブジェクトはReadOnlyCollectionを持っていました。コレクションは、直列化可能にするためにAddメソッドを実装する必要があります。


  • これは質問に対する正しい答えではありません。この質問にはすでに15の答えがあります。あなたの答えが他のものより優れていると思うなら、あなたはそれについてもっと多くの詳細を提供するべきです。いくつかのコードを提供します。出力スニペットは常にユーザーを助けます。回答を投稿する前に、読むことを検討してください - >stackoverflow.com/help/how-to-answer - Amit Phaltankar

リンクされた質問


関連する質問

最近の質問