2

オブジェクトをシリアル化するために、WCF の外部で DataContractSerializer を使用しようとしています。この場合のオブジェクトは CollectionBase の古いジェネリック ラッパーから継承します。

[KnownType(typeof(Foo)]
[CollectionDataContract]
class FooCollection : MyCollectionBase<Foo>

[KnownType(typeof(FooCollection)]
[KnownType(typeof(Foo)]
[CollectionDataContract]
class MyCollectionBase<T> : CollectionBase

[DataContract]
class Foo
{
    [DataMember]
    string Name;
    [DataMember]
    string Value;
}

これをシリアル化すると、次の構造が得られます。

<FooCollection xmlns="http://schemas.datacontract.org/ ...>
  <anyType>
    <Name>...</Name>
    <Value>...</Value>
  </anyType>
</ArrayOfAnyType>

デシリアライズすると、次のエラーが表示されます。

System.Runtime.Serialization.SerializationException : 名前空間http://schemas.datacontract.org/2004/07/MyAssemblyの要素 anyType は、オブジェクトとして逆シリアル化される子コンテンツを持つことはできません。このパターンの XML を逆シリアル化するには、XmlNode[] を使用してください。

----> System.Xml.XmlException : 名前空間 'http://schemas.datacontract.org/2004/07/MyAssembly' の終了要素 'anyType' が必要です。名前空間 'http://schemas.datacontract.org/2004/07/MyAssembly' から要素 'Name' が見つかりました。行 1、位置 xxx。

このエラーをグーグルで検索すると、シリアル化を機能させるために継承階層を変更したり、単にアプローチの問題をリストしたりする多くの人々が表示されます。XmlNode[] を使用してこのパターンの XML を逆シリアル化する例を見つけることができませんでした。

だから私の質問は:

  1. 基になる ArrayList に格納されている型が Foo 型であることを DataContractSerializer に納得させる方法はありますか?
  2. XmlNode[] 回避策を実装するにはどうすればよいですか?
  3. 非ジェネリック コレクションに支えられていないジェネリック コレクションを使用する唯一の解決策はありますか?
4

2 に答える 2

2

私は問題の原因を見つけましたが、元の質問には示されていません:MyCollectionBaseはISerializableを実装しました。

DataContractSerializerは、属性を使用する前にISerializable実装を使用します。また、ISerializableからコントラクトを推測できないため、anyType逆シリアル化の回避策はありません。

これが、KnownTypeAttributeが機能していなかった理由です。

于 2012-12-12T00:18:26.830 に答える