IEnumerable、ICollection<T>、および継承された型の XML シリアル化の防止
-
09-06-2019 - |
質問
注記: XML無視 は答えではありません!
さて、私の質問の続きです XML シリアル化と継承された型, 私はそのコードを自分が取り組んでいるアプリケーションに統合し始めましたが、愚かにもすべてがうまくいくだろうと考えていました。
実装しているいくつかのクラスで問題が発生しました IEnumerable そして Iコレクション<T>
これらの問題は、XMLSerializer がこれらをシリアル化するときに、それらを外部プロパティとして認識し、そのプロパティを使用する代わりに (つまり、私たちのもの AbstractXmlSerializer )ここに来て転倒し(型の不一致により)、ほぼ振り出しに戻ります。これらのメソッドを Xml無視 属性も同じなので、そのように停止することはできません。
私の現在の解決策は、インターフェイスの実装を削除することです(この現在のアプリケーションでは、それは実際には大したことではなく、コードをより美しくしただけです)。
これに関して自分のプライドを捨てて、それは不可能だと受け入れる必要がありますか? XmlSerializer を少しプッシュして、予想以上に多くのことを活用できたことはわかっています:)
編集
また、私は現在フレームワーク 2 で作業していることも付け加えておきます。
アップデート
受け入れました lomaxさんの答え. 。私のシナリオではこれを実際に行うことはできませんが、うまくいくことはわかっています。他に提案がなかったので、最終的にコードからインターフェイスの実装を削除しました。
解決
この問題は、System.RunTime.Serialization dll (.net 3.x アセンブリ) を取得し、.net 2.0 アプリケーションから参照することで回避できます。これが機能するのは、.net 3.0 バイナリが .net 2.0 CLR 上で実行されるようにコンパイルされているためです。
これを行うと、ICollection をパラメータとして Web サービスに渡したいのに、xmlserializer がそれを適切に処理する方法を知らなかったという同様の問題を回避するために使用した DataContractSerliazer にアクセスできるようになります。
2.x アプリケーションで .net 3.x dll を使用することに慣れている場合は、DataContractSerializer を使用してこの問題を解決できるはずです。
他のヒント
あなたの特定のアプリケーションに役立つには答えが来るのが遅すぎると思いますが、おそらく他にも同じ問題を抱えている人がいるでしょう。
この動作を回避するには、IEnumerable 型に IXmlSerializable を実装できると思います。ただし、これは、この型のシリアル化プロセスを完全に制御する必要があることを意味します。XmlReader / XmlWriter をいじる必要がないための簡単なアプローチでは、シリアル化するすべてのデータのパブリック ctor とパブリック読み取り/書き込みプロパティを使用してヘルパー XML アダプター クラスを作成し、内部にこの型の一時的な XmlSerializer オブジェクトを作成できます。 IXmlSerializable.[読み取り|書き込み]Xml()。
class Target : IEnumerable<Anything>, IXmlSerializable
{
//...
public void ReadXml(System.Xml.XmlReader reader)
{
reader.ReadStartElement();
TargetXmlAdapter toRead = (TargetXmlAdapter)new XmlSerializer(typeof(TargetXmlAdapter)).Deserialize(reader);
reader.Read();
// here: install state from TargetXmlAdapter
}
public void WriteXml(System.Xml.XmlWriter writer)
{
// NOTE: TargetXmlAdapter(Target) is supposed to store this' state being subject to serialization
new XmlSerializer(typeof(TargetXmlAdapter)).Serialize(writer, new TargetXmlAdapter(this));
}
}
これらの属性を使用する場合:
[XmlArray("ProviderPatientLists")]
[XmlArrayItem("File")]
public ProviderPatientList Files
{
get { return _ProviderPatientLists; }
set
{
_ProviderPatientLists = value;
}
}
ProviderPatientList が継承する場所 List<PatientList>
その後、出力されるxmlをより詳細に制御できます が作成されます