2008-09-13 3 views
298

C#.NET 2.0を使用して、[Serializable]属性を持つコンポジットデータクラスがあります。私はXMLSerializerクラスを作成し、コンストラクタに渡すことにしています:XmlSerializer - タイプを反映するエラーがありました

反射型エラーが発生しました:

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

私が言った例外を取得しています。

もう1つの複合オブジェクトがあります。これはまた、[Serializable]属性を持つ必要がありますか?それともトップオブジェクト上にあることによって、それを再帰的に内部のすべてのオブジェクトに適用しますか?

答えて

379

あなたが得ている内側の例外を見てください。それは、どのフィールド/プロパティがシリアル化に問題があるかを示します。

[XmlIgnore]属性を使用してxmlシリアル化からフィールド/プロパティをデコレートできます。

XmlSerializer[Serializable]属性を使用しているとは思わないので、それは問題ではないでしょうか。

+11

オブジェクトにUriフィールドがあり、この例外が発生しました。 Uriクラスにはパラメータのないコンストラクタがありません。先端に感謝します。 – ford

+7

Google検索でこれを見つけました。私の特有の問題は、リストにする必要があるときに、IListとしての「シリアライズ」クラスのプロパティを持つことでした。 –

+7

「内部例外」をどのように見ますか? – David

0

また、ユーザーインターフェイスコントロールをシリアル化できず、クリップボードに渡すオブジェクトはシリアル化可能でなければならず、そうでなければ他のプロセスに渡すことはできません。

2

..あなたは、シリアル化プロセスにさらにデバッグする場合、これらのリンクをチェックし、ブラックボックスでありますオブジェクトが、完全なnoob(私は深夜のコーディングセッションの途中です)でない限り、SnippetCompilerから

私は、XmlSerializerがパブリックプロパティに対してリフレクションを使用していると思います。

105

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

+4

リマインダーありがとう!私はこれが少しの説明でランタイムエラーであることは嫌いです。 –

+0

私はこの間違いを何度も繰り返し続けています。パラメータのないコンストラクタを使用するように覚えてくれてありがとう^^ –

6

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

XML Serialization and Inherited Types

0

私は をシリアライズするNetDataSerialiserクラスを使用しています私のドメインクラス。 NetDataContractSerializer Class

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

4

.NET 2.0のDictionaryクラスはXMLを使用してシリアル化できないことが判明しましたが、バイナリシリアル化を使用するとうまくシリアル化されます。

私はhereの問題を発見しました。

4

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をを「拡張」する洗練された方法を実装するためのエレガントな方法を示して面白いarticle、があります。

IXmlSerializableは公式ドキュメントで説明されていますが、ドキュメントは、それが公共の使用を意図していない状態と、それを超えた情報を提供しない:


記事は言います。これは、開発チームが、この拡張性を変更、無効化、または完全に削除する権利を確保したかったことを示しています。しかし、あなたがこの不確実性を受け入れ、将来の可能性のある変化に対処することができれば、それを利用できない理由は何もありません。

これは、あまりにも複雑な実装を避けるため、私はあなた自身のIXmlSerializableクラスを実装することをお勧めします。

...リフレクションを使用してカスタムXmlSerializerクラスを実装するのは簡単です。

3

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

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

は私が自動生成されたシーケンスの最後のより高次のものと同様の属性を追加するために必要な、これは私のためにそれを修正しました。

20

私も同様の問題がありました。シリアライザは同じ名前の2つのクラスを区別できませんでした(一方はもう一方のサブクラスでした)。

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

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

[XmlType("BaseNamespace.Class1")] 

注:あなたがクラスの複数の層を持っている場合は、に属性を追加する必要があり、私が行うために必要な何

は(私は基本クラスに追加)クラスの1つに属性を追加しましたそれらも同様です。

+0

これは私にとって問題を修正しました。私はいくつかのProcessor *オブジェクトと同様の設定をしていました。それぞれはConfig内部クラスを持ちます。ランタイムはSomeNS.Processor1.ConfigとSomeNS.Processor2.Configを区別できませんでした。 – damix911

1

ちょうど同じエラーが発生し、タイプがIEnumerable<SomeClass>のプロパティが問題であることが判明しました。 IEnumerableを直接シリアル化することはできないようです。

1

は私が注文が行

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

....いくつかのコード内の2つの要素のために同じであったような状況を...持っていた私はインクリメントするコードを変更し

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

クラス内の新しいPropertyごとに1つずつ順番に並べ替えると、エラーはなくなりました。私によって

4

最も一般的な理由:

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

[System.Xml.Serialization.XmlElementAttribute( "strFieldName"、フォーム= System.Xml.Schema.XmlSchemaForm.Unqualified)]

//あるいは

[XmlIgnore] 文字列[] strFielsName取得または設定;}

0

私は同じ問題を持っていたし、私の場合にはオブジェクトがReadOnlyCollectionを持っていました。コレクションは、シリアライズ可能なAddメソッドを実装する必要があります。

+0

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

関連する問題