次の方法で共有


XML シリアル化

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

XML シリアル化では、オブジェクトのパブリック フィールドとプロパティ値のみが XML ストリームにシリアル化されます。 XML シリアル化には型情報は含まれません。 たとえば、Library 名前空間に存在する Book オブジェクトがある場合、同じ型のオブジェクトに逆シリアル化される保証はありません。

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

XML シリアル化の中心クラスは XmlSerializer クラスであり、このクラスの最も重要なメソッドは Serialize メソッドと Deserialize メソッドです。 XmlSerializerは C# ファイルを作成し、.dll ファイルにコンパイルしてこのシリアル化を実行します。 XML シリアライザー ジェネレーター ツール (Sgen.exe) は、これらのシリアル化アセンブリを事前に生成して、アプリケーションと共にデプロイし、スタートアップ パフォーマンスを向上させるように設計されています。 XmlSerializer によって生成される XML ストリームは、World Wide Web Consortium (W3C) XML スキーマ定義言語 (XSD) 1.0 の推奨事項に準拠しています。 さらに、生成されるデータ型は、「XML スキーマ パート 2: データ型」というタイトルのドキュメントに準拠しています。

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

XML スキーマがある場合は、XML スキーマ定義ツールを実行して、スキーマに厳密に型指定され、属性で注釈が付けられたクラスのセットを生成できます。 このようなクラスのインスタンスがシリアル化されると、生成された XML は XML スキーマに準拠します。 このようなクラスを使用すると、生成された XML が XML スキーマに準拠していることを保証しながら、簡単に操作できるオブジェクト モデルに対してプログラミングできます。 これは、 XmlReader クラスや XmlWriter クラスなど、.NET の他のクラスを使用して XML ストリームを解析および書き込む代わりに使用します。 詳細については、「 XML ドキュメントとデータ」を参照してください。 これらのクラスを使用すると、任意の XML ストリームを解析できます。 これに対し、XML ストリームが既知の XML スキーマに準拠することが予想される場合は、 XmlSerializer を使用します。

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

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

XmlSerializer クラスは、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 は C# (.cs) ファイルを作成し、TEMP 環境変数によって名前付けされたディレクトリ内の .dll ファイルにコンパイルします。シリアル化は、これらの DLL で行われます。

    これらのシリアル化アセンブリは、事前に生成し、SGen.exe ツールを使用して署名できます。 これは、Web サービスのサーバーでは機能しません。 言い換えると、クライアントの使用と手動のシリアル化に対してのみ行われます。

    コードと DLL は、作成時とコンパイル時の悪意のあるプロセスに対して脆弱です。 2 人以上のユーザーが TEMP ディレクトリを共有できる場合があります。 2 つのアカウントに異なるセキュリティ特権があり、高い特権のアカウントが XmlSerializer を使用してアプリケーションを実行する場合、TEMP ディレクトリの共有は危険です。 この場合、1 人のユーザーが、コンパイルされた.csまたは .dll ファイルを置き換えることで、コンピューターのセキュリティを侵害する可能性があります。 この問題を解消するには、常にコンピューター上の各アカウントに独自のプロファイルがあることを確認してください。 既定では、TEMP 環境変数はアカウントごとに異なるディレクトリを指します。

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

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

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

    悪意のあるオブジェクトが脅威を提示する方法は 2 つあります。 悪意のあるコードを実行したり、 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 を実装するクラス。

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

  • XmlElement オブジェクト。

  • XmlNode オブジェクト。

  • DataSet オブジェクト。

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

XML シリアル化を使用する利点

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

たとえば、 XmlSerializer を使用すると、次のことが可能になります。

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

  • 使用する XML 名前空間を指定します。

  • フィールドまたはプロパティ名が不適切な場合は、要素または属性の名前を指定します。

XML シリアル化のもう 1 つの利点は、生成される XML ストリームが特定のスキーマに準拠している限り、開発するアプリケーションに制約がないということです。 書籍の記述に使用されるスキーマを想像してみてください。 タイトル、作成者、発行元、および ISBN 番号要素を備えています。 書籍の注文や書籍のインベントリなど、任意の方法で XML データを処理するアプリケーションを開発できます。 どちらの場合も、唯一の要件は、XML ストリームが指定された XML スキーマ定義言語 (XSD) スキーマに準拠していることです。

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

XmlSerializer クラスを使用する場合は、次の内容を考慮する必要があります。

  • Sgen.exe ツールは、最適なパフォーマンスを得るためにシリアル化アセンブリを生成するように明示的に設計されています。

  • シリアル化されたデータには、データ自体とクラスの構造のみが含まれます。 型 ID とアセンブリ情報は含まれません。

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

  • クラスには、 XmlSerializer によってシリアル化されるパラメーターなしのコンストラクターが必要です。

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

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

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

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

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

XSD データ型のマッピング

XML スキーマパート 2: Datatypes 」というタイトルの W3C ドキュメントでは、XML スキーマ定義言語 (XSD) スキーマで許可される単純なデータ型を指定します。 これらの多くの場合 ( intdecimal など)、.NET には対応するデータ型があります。 ただし、一部の XML データ型には、対応する .NET データ型 ( 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 プロパティを参照してください。

こちらも参照ください