シリアル化とメタデータ
アプリでオブジェクトをシリアル化および逆シリアル化する場合、ランタイム ディレクティブ (.rd.xml) ファイルにエントリを追加して、必要なメタデータが実行時に確実に存在するようにする必要があることがあります。 シリアライザーには次の 2 つのカテゴリがあり、それぞれランタイム ディレクティブ ファイルで異なる処理が必要です。
リフレクション ベースのサードパーティ シリアライザー。 この場合、ランタイム ディレクティブ ファイルの変更が必要です。詳細については次のセクションで説明します。
.NET Framework クラス ライブラリにある非リフレクション ベースのシリアライザー。 この場合、ランタイム ディレクティブ ファイルの変更が必要なことがあります。詳細については、「Microsoft のシリアライザー」セクションで説明します。
サードパーティ シリアライザー
Newtonsoft.JSONを含むサード パーティのシリアライザーは、通常、リフレクション ベースです。 シリアル化データのバイナリ ラージ オブジェクト (BLOB) の場合、対象の型のフィールドを名前で検索することで、データ内のフィールドが具象型に割り当てられます。 少なくとも、これらのライブラリを使用すると、List<Type>
コレクションでシリアル化または逆シリアル化しようとする Type オブジェクトごとに MissingMetadataException 例外が発生します。
これらのシリアライザーでメタデータの欠落により引き起こされる問題に対処する最も簡単な方法は、1 つの名前空間 (App.Models
など) でシリアル化に使用される型を収集し、Serialize
メタデータ ディレクティブを適用することです。
<Namespace Name="App.Models" Serialize="Required PublicAndInternal" />
この例で使用されている構文の詳細については、「<Namespace> 要素」を参照してください。
Microsoft のシリアライザー
DataContractSerializer、DataContractJsonSerializer、および XmlSerializer クラスではリフレクションを利用しませんが、シリアル化または逆シリアル化されるオブジェクトに基づいてコードが生成される必要があります。 各シリアライザーのオーバーロードされたコンストラクターには、シリアル化または逆シリアル化される型を指定する Type パラメーターが含まれます。 次の 2 つのセクションで説明するように、コードでのその型の指定方法によってユーザーが実行する必要のあるアクションが定義されます。
コンストラクターで使用される typeof
これらのシリアル化クラスのコンストラクターを呼び出し、メソッド呼び出しに C# typeof 演算子を含めた場合、それ以外に行う必要がある作業はありません。 たとえば、シリアル化クラス コンストラクターに対する次の各呼び出しでは、typeof
キーワードがコンストラクターに渡される式の一部として使用されます。
XmlSerializer xmlSer = new XmlSerializer(typeof(T));
DataContractSerializer dataSer = new DataContractSerializer(typeof(T));
DataContractJsonSerializer jsonSer = new DataContractJsonSerializer(typeof(T));
.NET ネイティブ コンパイラは、このコードを自動的に処理します。
コンストラクターの外部で使用される typeof
次のコードのように、これらのシリアル化クラスのコンストラクターを呼び出し、コンストラクターの Type パラメーターに提供する式の外部で C# typeof 演算子を使用する場合、.NET Native コンパイラによって型を解決することはできません。
Type t = typeof(DataSet);
XmlSerializer ser = new XmlSerializer(t);
この場合は、次のようなエントリを追加して、ランタイム ディレクティブ ファイルで型を指定する必要があります。
<Type Name="DataSet" Browse="Required Public" />
同様に、次のコードのように XmlSerializer(Type, Type[]) などのコンストラクターを呼び出し、シリアル化する追加の Type オブジェクトの配列を指定した場合も、.NET ネイティブ コンパイラはこれらの型を解決できません。
XmlSerializer xSerializer = new XmlSerializer(typeof(Teacher),
new Type[] { typeof(Student),
typeof(Course),
typeof(Location) });
型ごとに次のようなエントリをランタイム ディレクティブ ファイルに追加する必要があります。
<Type Name="t" Browse="Required Public" />
この例で使用されている構文の詳細については、「<Type> 要素」を参照してください。