Share via


XML シリアル化の概要

シリアル化とは、オブジェクトを簡単に転送できる形式に変換する処理です。たとえば、オブジェクトをシリアル化し、HTTP を使用してインターネット経由でクライアントとサーバー間で転送できます。一方、逆シリアル化とは、ストリームから元のオブジェクトを再構築する処理です。

XML シリアル化は、オブジェクトのパブリック フィールドとパブリック プロパティの値だけを XML ストリームにシリアル化します。XML シリアル化では、型情報は対象に含まれません。たとえば、Library 名前空間に Book オブジェクトがある場合は、逆シリアル化時に、ストリームから同じ型のオブジェクトが再構築されるという保証はありません。

Noteメモ :

XML シリアル化では、メソッド、インデクサ、プライベート フィールド、または読み取り専用プロパティ (読み取り専用コレクションを除く) は変換されません。オブジェクトのフィールドとプロパティを (パブリックであるかプライベートであるかを問わず) すべてシリアル化するには、XML シリアル化ではなく BinaryFormatter を使用します。

XML シリアル化の中心的役割を果たすクラスは XmlSerializer クラスです。このクラスの最も重要なメソッドは、Serialize メソッドと Deserialize メソッドです。XmlSerializer は、C# ファイルを作成し、これを .dll ファイルにコンパイルすることによって、シリアル化を行います。.NET Framework 2.0 では、アプリケーションと共に配置する前にこうしたシリアル化アセンブリを生成し、起動時のパフォーマンスを向上させるための、XML シリアライザ ジェネレータ ツール (Sgen.exe) が用意されています。XmlSerializer によって生成される XML ストリームは、W3C (World Wide Web Consortium) (www.w3.org) 勧告『XML Schema definition language (XSD) 1.0』に準拠します。さらに、生成されるデータ型は、ドキュメント『XML Schema Part 2: Datatypes』に準拠します。

オブジェクト内のデータは、クラス、フィールド、プロパティ、プリミティブ型、配列などのプログラミング構成要素だけでなく、埋め込み XML (XmlElement または XmlAttribute オブジェクト) を使用して記述されます。属性で注釈を付けて独自のクラスを作成するか、または XML スキーマ定義ツールを使用して、既存の XML スキーマに基づいたクラスを生成できます。

XML スキーマがある場合は、XML スキーマ定義ツールを実行して、そのスキーマに型が厳密に適合する一連のクラスを生成し、属性を使用してそのクラスに注釈を付けることができます。このようなクラスのインスタンスをシリアル化した場合、元の XML スキーマに準拠した XML が生成されます。このようなクラスを用意すると、操作が簡単なオブジェクト モデルを使用してプログラミングできると同時に、生成される XML も確実に XML スキーマに準拠したものになります。.NET Framework の他のクラス (XmlReader クラス、XmlWriter クラスなど) を使用する代わりに、この方法を使用して XML ストリームの解析や書き込みを実行できます。詳細については、「XML ドキュメントと XML データ」を参照してください。これらのクラスを使用すると、任意の XML ストリームを解析できます。これに対し、XML ストリームを既知の XML スキーマに準拠させる必要がある場合には、XmlSerializer を使用します。

属性を使用して、XML ストリームの XML 名前空間、要素名、属性名などを設定することで、XmlSerializer クラスによって生成される XML ストリームを制御できます。これらの属性、およびそれらによって XML シリアル化を制御する方法については、「属性を使用した XML シリアル化の制御」を参照してください。また、生成される XML を制御するこれらの属性の表については、「XML シリアル化を制御する属性」を参照してください。

さらに、XmlSerializer クラスでは、オブジェクトをシリアル化し、エンコード済みの SOAP XML ストリームを生成することもできます。このようにして生成される XML は、W3C のドキュメント『Simple Object Access Protocol (SOAP) 1.1』のセクション 5 に準拠します。このプロセスの詳細については、「方法 : オブジェクトを SOAP エンコード済み XML ストリームとしてシリアル化する」を参照してください。生成される XML を制御する属性の表については、「エンコード済み SOAP シリアル化を制御する属性」を参照してください。

XmlSerializer クラスは、XML Web サービスによって作成され、XML Web サービスに渡される SOAP メッセージを生成します。この SOAP メッセージを制御するには、XML Web サービス ファイル (.asmx) 内のクラス、戻り値、パラメータ、およびフィールドに属性を適用します。XML Web サービスでは、リテラルまたはエンコード済みのいずれの SOAP スタイルも使用できるため、「XML シリアル化を制御する属性」と「エンコード済み SOAP シリアル化を制御する属性」の両方に示されている属性を使用できます。属性を使用して XML Web サービスによって生成される XML を制御する方法については、「XML Web サービスを使用した XML シリアル化」を参照してください。SOAP と XML Web サービスの詳細については、「SOAP メッセージ形式のカスタマイズ」を参照してください。

XmlSerializer アプリケーションのセキュリティに関する考慮事項

XmlSerializer を使用するアプリケーションを作成するときは、次の項目とその関連事項に注意する必要があります。

  • XmlSerializer は、TEMP 環境変数で指定されたディレクトリ内に C# ファイル (.cs) を作成し、これらを .dll ファイルにコンパイルします。シリアル化はこれらの DLL で行われます。

    Noteメモ :

    SGen.exe ツールを使用して、このシリアル化アセンブリを事前に作成して署名することができます。これは、サーバー側の Web サービスに対しては機能しません。つまり、クライアント側での手動によるシリアル化でのみ使用できます。

    コードと DLL には、作成時とコンパイル時に、悪意のあるプロセスに対して脆弱性があります。Microsoft Windows NT 4.0 以降を実行しているコンピュータでは、複数のユーザーが一時ディレクトリを共有する可能性があります。2 つのアカウントが異なるセキュリティ特権を持ち、高い特権を持つアカウントが XmlSerializer を使用してアプリケーションを実行する場合、一時ディレクトリを共有することは危険です。この場合は、一方のユーザーが .cs ファイルまたはコンパイルされた .dll ファイルのどちらかを置き換えることによって、コンピュータのセキュリティを侵害することが可能になります。これを防ぐためには、コンピュータ上の各アカウントが常に固有のプロファイルを持つようにしてください。既定では、TEMP 環境変数は各アカウントごとに異なるディレクトリを示します。

  • 悪意のあるユーザーが XML データの連続ストリームを Web サーバーに送り続けると (サービス拒否攻撃)、コンピュータがリソース不足に陥るまで、XmlSerializer はデータの処理を続行します。

    この種類の攻撃は、インターネット インフォメーション サービス (IIS) を実行しているコンピュータを使用し、IIS 内でアプリケーションを実行することによって防ぐことができます。IIS には、設定された量 (既定では 4 KB) を超える長さのストリームを処理しないゲート機能があります。IIS を使用しないアプリケーションを作成し、XmlSerializer による逆シリアル化を行う場合は、サービス拒否攻撃を防ぐ同様のゲート機能を実装する必要があります。

  • XmlSerializer はデータをシリアル化し、与えられた任意の型を使用してすべてのコードを実行します。

    悪意のあるオブジェクトが脅威を与える方法として、次の 2 とおりがあります。1 つは悪意のあるコードを実行する方法であり、もう 1 つは、XmlSerializer によって作成された C# ファイルに悪意のあるコードを挿入する方法です。最初のケースでは、悪意のあるオブジェクトが破壊的なプロシージャを実行しようとしたときに、コード アクセス セキュリティによって実行が妨げられ、破壊を防ぐことができます。2 番目のケースでは、XmlSerializer によって作成された C# ファイルに、悪意のあるオブジェクトがなんらかの方法でコードを挿入する理論的な可能性はあります。この問題は十分に調査され、このような攻撃を受ける確率は低いと思われますが、不明または信頼のない型のデータは絶対にシリアル化しないという警戒が必要です。

  • 機密データをシリアル化すると脆弱性が生じる可能性があります。

    XmlSerializer がシリアル化したデータは、XML ファイルとして格納されるか、または他のデータ ストアに格納されます。このデータ ストアが他のプロセスからも利用できたり、イントラネットまたはインターネットで表示できたりする場合は、データの盗用や悪意のある使用などの可能性があります。たとえば、クレジット カード番号を含む注文をシリアル化するアプリケーションを作成すると、データは非常に脆弱になります。これを避けるには、データのストアを常に保護し、プライベートに保つための処置が必要です。

単純なクラスのシリアル化

パブリック フィールドを持つ単純なクラスのコード例を次に示します。

Public Class OrderForm
    Public OrderDate As DateTime
End Class
public class OrderForm
{
    public DateTime OrderDate;
}

このクラスのインスタンスをシリアル化すると、次のようなストリームが生成されます。

<OrderForm>
    <OrderDate>12/12/01</OrderDate>
</OrderForm>

シリアル化の例については、「XML シリアル化の例」を参照してください。

シリアル化できる項目

XmLSerializer クラスを使用してシリアル化できる項目を次に示します。

  • パブリックな読み取り/書き込みプロパティとパブリック クラスのフィールド

  • ICollection または IEnumerable を実装するクラス

    Noteメモ :

    パブリック プロパティではなく、コレクションだけがシリアル化されます。

  • XmlElement オブジェクト

  • XmlNode オブジェクト

  • DataSet オブジェクト

オブジェクトのシリアル化または逆シリアル化の詳細については、「方法 : オブジェクトをシリアル化する」および「方法 : オブジェクトを逆シリアル化する」を参照してください。

XML シリアル化の利点

XmlSerializer クラスを使用すると、オブジェクトを XML としてシリアル化するときに、シリアル化を完全かつ柔軟に制御できます。XML Web サービスを作成する場合は、シリアル化を制御する属性をクラスやメンバに適用すると、XML 出力を特定のスキーマに準拠させることができます。

たとえば、XmlSerializer を使用すると、次のような内容を指定できます。

  • フィールドやプロパティを属性または要素としてエンコードするかどうか

  • 使用する XML 名前空間

  • 要素または属性の名前 (フィールド名やプロパティ名が適切ではない場合)

XML シリアル化のもう 1 つの利点は、生成される XML ストリームが特定のスキーマに準拠している限りは、開発するアプリケーションに制約が課されないことです。たとえば、書籍の説明に使用するスキーマがあるとします。このスキーマでは、書籍名、著者、出版社、および ISBN 番号といった要素を扱います。この場合、この XML データを任意の方法で処理するアプリケーション (書籍の発注や在庫管理を行うアプリケーションなど) を開発できます。いずれの場合も、指定された XML スキーマ定義言語 (XSD) スキーマに XML ストリームが準拠していることが唯一の要件です。

XML シリアル化に関する考慮事項

XmlSerializer クラスを使用する場合に考慮すべき事項を次に示します。

  • Sgen.exe ツールは、シリアル化アセンブリを生成して最適なパフォーマンスを実現することを明確な目的としています。

  • シリアル化されたデータには、データそのものとクラスの構造が含まれています。型の識別子やアセンブリの情報は含まれません。

  • シリアル化できるのは、パブリック プロパティとパブリック フィールドだけです。非パブリック データをシリアル化する必要がある場合は、XML シリアル化ではなく BinaryFormatter クラスを使用します。

  • クラスを XmlSerializer でシリアル化するには、そのクラスに既定のコンストラクタがあることが必要です。

  • メソッドはシリアル化できません。

  • IEnumerable または ICollection を異なる方法で実装している複数のクラスは、次のような特定の要件を満たしていれば、XmlSerializer で処理できます。

    IEnumerable を実装するクラスは、単一のパラメータを受け取るパブリックな Add メソッドを実装する必要があります。Add メソッドのパラメータは、GetEnumerator メソッドによって返される IEnumerator.Current プロパティから返される型と一致している (ポリモーフィックである) 必要があります。

    IEnumerable の他に ICollection も実装するクラス (CollectionBaseなど) は、整数を受け取るパブリックなインデックス付き Itemプロパティ (C# の場合はインデクサ) と、整数型のパブリックな Count プロパティを持っている必要があります。Add メソッドに渡されるパラメータは、Item プロパティから返された型と同じ型か、またはその型の基本型の 1 つであることが必要です。

    ICollection を実装するクラスの場合、シリアル化される値は、GetEnumerator を呼び出して取得されるのではなく、インデックス付き Item プロパティから取得されます。また、パブリック フィールドとパブリック プロパティは、別のコレクション クラス (ICollection を実装するクラス) を返すパブリック フィールドを除き、シリアル化されません。例については、「XML シリアル化の例」を参照してください。

XSD データ型のマッピング

W3C (World Wide Web Consortium) (www.w3.org) のドキュメント『XML Schema Part 2: Datatypes』では、XML スキーマ定義言語 (XSD) スキーマで使用できる単純なデータ型が指定されています。これらのデータ型 (intdecimal など) の多くについては、対応するデータ型が .NET Framework にあります。ただし、.NET Framework には対応するデータ型がない XML データ型 (NMTOKEN データ型など) もあります。その場合は、XML スキーマ定義ツール (XML スキーマ定義ツール (Xsd.exe)) を使用してスキーマからクラスを生成すると、適切な属性が文字列型のメンバに適用され、その DataType プロパティが XML データ型名に設定されます。たとえば、XML データ型が NMTOKEN である "MyToken" という名前の要素がスキーマに含まれている場合、生成されるクラスには、次の例に示すようなメンバが含まれます。

<XmlElement(DataType:="NMTOKEN")> _
Public MyToken As String
[XmlElement(DataType = "NMTOKEN")]
public string MyToken;

同様に、特定の XML スキーマ (XSD) に準拠する必要があるクラスを作成する場合は、そのクラスに適切な属性を適用し、その DataType プロパティを必要な XML データ型名に設定する必要があります。

型のマッピングの完全な一覧については、次のいずれかの属性クラスの DataType プロパティを参照してください。

参照

処理手順

方法 : オブジェクトをシリアル化する
方法 : オブジェクトを逆シリアル化する

関連項目

XMLSerializer.Serialize
BinaryFormatter
XmlSerializer
FileStream

概念

XML シリアル化の例

その他の技術情報

XML シリアル化および SOAP シリアル化
バイナリ シリアル化
シリアル化