実装が簡単でありながら、.NET オブジェクトの最も柔軟なシリアル化は何ですか?
-
01-07-2019 - |
質問
クラスグラフ全体を気にせずにオブジェクトをシリアル化および逆シリアル化したいと考えています。
柔軟性が重要です。オブジェクト グラフ全体で必要な完全な属性なしで、渡されたオブジェクトをシリアル化できるようにしたいと考えています。
つまり、バイナリシリアル化は他の.NETプラットフォームでのみ動作するため、オプションではありません。また、人が読みやすいものを望んでいるので、管理プログラムや他の通訳者が解読可能です。
DataContract、JSON、および XML シリアライザーの使用時に問題が見つかりました。
- これらのエラーのほとんどは、リスト/辞書のシリアル化に集中しているようです (つまり、 XML シリアル化可能な汎用辞書).
- 「既知のタイプのリストに静的に既知のタイプを追加します。たとえば、既知のTypeattribute属性を使用するか、既知のタイプのリストに追加された既知のタイプのリストに追加します。」
理論や記事を読んだのではなく、実際の経験に基づいて回答してください。
解決
XML ではなく JSON へのシリアル化を検討したことがありますか?
Json.NET には、ハッシュテーブル/汎用辞書に問題がなく、特定の属性を必要としない、非常に強力で柔軟なシリアライザーが備わっています。私が書いたので知っています:)
これにより、シリアライザーのさまざまなオプションを通じて大量の制御が可能になり、型の JsonConverter を作成することで型のシリアル化方法をオーバーライドできるようになります。
私の意見では、JSON は XML よりも人間が読みやすいものであり、Json.NET には適切な形式の JSON を作成するオプションが用意されています。
最後に、プロジェクトはオープンソースなので、必要に応じてコードにステップインして変更を加えることができます。
他のヒント
私が思い出したように、プロパティでは次のように機能します。
[XmlArray("Foo")]
[XmlArrayItem("Bar")]
public List<BarClass> FooBars
{ get; set; }
これをシリアル化すると、次のような結果が得られます。
<Foo>
<Bar />
<Bar />
</Foo>
もちろん、専門家に頼るべきかもしれません。MS からの詳細情報は次のとおりです。 http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlarrayitemattribute.aspx
それがうまくいくかどうか教えてください。
要件からすると、Xml シリアル化が最適のようです。
連載時にコレクションに関してどのような問題がありますか?リストまたは同様のもので使用する属性がわからない場合は、プロパティのXMLARRAY属性を試すことができます。間違いなくコレクションをシリーズ化することができます。
XNA Framework の IntermediateSerializer は非常に優れています。これを使用するためのチュートリアルがたくさんあります。 http://blogs.msdn.com/shawnhar
[Serializable] のマークが付いていないオブジェクトであっても、SOAP シリアル化はうまく機能しました。
コレクション内のオブジェクトに同じコレクション内の他のオブジェクトへの参照が含まれている場合、コレクションのシリアル化で問題が発生します。何らかのタイプのデュアルポインティングが存在すると、シリアル化できないマルチマップを作成することになります。これまでカスタム コレクションのシリアル化で発生したすべての問題は、常に、「典型的な」クライアント/サーバー アプリケーションの一部としては正常に動作するものの、コンシューマ プロバイダーの一部として惨めに失敗する、必要な追加機能が原因でした。 -サーバーアプリケーション。
シリアル化するすべてのクラスを別のアセンブリに配置し、sgen ツールを使用して XML にシリアル化するシリアル化アセンブリを生成します。XML 属性を使用してシリアル化を制御します。
シリアル化アセンブリをカスタマイズする必要がある場合 (そして、 意思 IXmlSerializable ではないクラスや抽象ノードを含むクラスをサポートする必要がある場合)、ソース コードを別のファイルにダンプしてソリューションに追加するように sgen に指示します。その後、必要に応じて変更できます。
http://msdn.microsoft.com/en-us/library/bk3w6240(VS.80).aspx
FWIW さん、私はこの手法を使用して AdsML フレームワーク全体 (400 クラス以上) をシリアル化することができました。多くの手動カスタマイズが必要でしたが、フレームワークのサイズを考慮すると、それを回避することはできません。(XSD から C# に移行するために別のツールを使用しました)
DataContract ベースのシリアル化メソッド (JSON、XML など) が私が望むよりも少し複雑であることに同意します。
JSON を取得しようとしている場合は、チェックアウトしてください http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
これは MS AJAX 拡張機能の一部です。確かに、.NET 3.5 では廃止済みとしてフラグが立てられていますが、ScottGu はここのブログ コメントで言及しています (http://weblogs.asp.net/scottgu/archive/2007/10/01/tip-trick-building-a-tojson-extension-method-using-net-3-5.aspx#4301973)その理由はわからないが、もう少し長くサポートされるべきだと彼は言いました。
最も簡単な方法は、オブジェクトを Serializable 属性でマークし、バイナリ フォーマッタを使用してシリアル化を処理することです。含まれているオブジェクトもシリアル化可能としてマークされていれば、クラス グラフ全体が問題になることはありません。
おそらく、より効率的な方法は、BinaryFormatter を使用してシリアル化することです。
からコピーしたものとして http://blog.paranoidferret.com/index.php/2007/04/27/csharp-tutorial-serialize-objects-to-a-file/
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public class Serializer
{
public Serializer()
{
}
public void SerializeObject(string filename,
ObjectToSerialize objectToSerialize)
{
Stream stream = File.Open(filename, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, objectToSerialize);
stream.Close();
}
public ObjectToSerialize DeSerializeObject(string filename)
{
ObjectToSerialize objectToSerialize;
Stream stream = File.Open(filename, FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
objectToSerialize =
(ObjectToSerialize)bFormatter.Deserialize(stream);
stream.Close();
return objectToSerialize;
}
}
相互運用性のために、私たちは常に Xml シリアル化を使用し、それを正しく実行できるようにクラスが最初から設計されていることを確認しました。
XSD スキーマ ドキュメントを作成し、XSD.exe を使用してそこからクラスのセットを生成します。これにより部分クラスが生成されるため、対応する部分クラスのセットを作成して、クラスにデータを設定してアプリケーションで使用するのに役立つ追加のメソッドを追加します (メソッドはシリアル化と逆シリアル化に焦点を当てており、場合によっては少し使いにくいため) )。
NetDataContractSerializer を使用する必要があります。あらゆる種類のオブジェクト グラフをカバーし、ジェネリック、リスト、ポリモーフィズム (ここでは KnownType 属性は必要ありません)、再帰などをサポートします。唯一の欠点は、すべてのクラスに [Serializable] / [DataContract] 属性をマークする必要があることですが、経験上、すべてのメンバーを永続化する必要はないため、いずれにしても何らかの手動微調整を行う必要があることがわかっています。また、Xml にシリアル化されますが、可読性には疑問があります。
私たちもお客様と同じ要件を持っており、このソリューションを選択しました。