シリアル化と逆シリアル化

Windows Communication Foundation (WCF) には、新しいシリアル化エンジン、DataContractSerializer が含まれています。 DataContractSerializer は、.NET Framework オブジェクトと XML を双方向に変換します。 ここでは、シリアライザーのしくみについて説明します。

.NET Framework オブジェクトをシリアル化するときに、シリアライザーは、新しいデータ コントラクト モデルも含め、さまざまなシリアル化プログラミング モデルを認識します。 サポートされるすべての型の一覧については、「 Types Supported by the Data Contract Serializer」を参照してください。 データ コントラクトの概要については、「 Using Data Contracts」を参照してください。

XML を逆シリアル化するときに、シリアライザーは XmlReader クラスと XmlWriter クラスを使用します。 また、WCF バイナリ XML 形式を使用する場合などに、最適化された XML を生成できるように、XmlDictionaryReader クラスと XmlDictionaryWriter クラスもサポートしています。

WCF には、コンパニオン シリアライザーである NetDataContractSerializer も含まれます。 NetDataContractSerializer:

  • セキュリティで保護されていません。 詳細については、「BinaryFormatter セキュリティ ガイド」を参照してください。
  • BinaryFormatter シリアライザーや SoapFormatter シリアライザーに似ています。これは、シリアル化されたデータの一部として .NET Framework 型名も出力されるためです。
  • シリアル化と逆シリアル化の終了時に、同じ型を共有する場合に使用されます。

DataContractSerializerNetDataContractSerializer はどちらも、共通の基底クラス、XmlObjectSerializer から派生します。

警告

DataContractSerializer は、20 未満の 16 進数値と制御文字を含む文字列を XML エンティティとしてシリアル化します。 このため、そのようなデータを WCF サービスに送信しているときに、WCF 以外のクライアントに問題が発生することがあります。

DataContractSerializer インスタンスの作成

DataContractSerializer のインスタンスの作成は重要な手順です。 インスタンスの作成後に、設定を変更することはできません。

ルート型の指定

ルート型 は、シリアル化または逆シリアル化するインスタンスの型です。 DataContractSerializer には、多数のコンストラクター オーバーロードがありますが、 type パラメーターを使用して、少なくともルート型を指定する必要があります。

特定のルート型に対応するシリアライザーを作成した場合、このシリアライザーを使用して別の型をシリアル化 (または逆シリアル化) することはできません。ただし、対象の型がルート型の派生型である場合を除きます。 2 つのクラスを次の例に示します。

[DataContract]
public class Person
{
    // Code not shown.
}

[DataContract]
public class PurchaseOrder
{
    // Code not shown.
}
<DataContract()> _
Public Class Person
    ' Code not shown.
End Class

<DataContract()> _
Public Class PurchaseOrder
    ' Code not shown.
End Class

DataContractSerializer クラスのインスタンスをシリアル化または逆シリアル化する場合にのみ使用できる Person のインスタンスを作成するコードを次に示します。

DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
// This can now be used to serialize/deserialize Person but not PurchaseOrder.
Dim dcs As New DataContractSerializer(GetType(Person))
' This can now be used to serialize/deserialize Person but not PurchaseOrder.

既知の型の指定

KnownTypeAttribute 属性またはその他の機構を使用してまだ処理されていないシリアル化対象の型にポリモーフィズムが必要な場合、 knownTypes パラメーターを使用して、存在し得る既知の型のリストをシリアライザーのコンストラクターに渡す必要があります。 既知の型の詳細については、「既知のデータ コントラクト型」を参照してください。

LibraryPatron型のコレクションを含む LibraryItemクラスの例を次に示します。 2 番目のクラスでは、 LibraryItem 型を定義しています。 3 番目と 4 番目のクラス (BookNewspaper) は、 LibraryItem クラスを継承しています。

[DataContract]
public class LibraryPatron
{
    [DataMember]
    public LibraryItem[] borrowedItems;
}
[DataContract]
public class LibraryItem
{
    // Code not shown.
}

[DataContract]
public class Book : LibraryItem
{
    // Code not shown.
}

[DataContract]
public class Newspaper : LibraryItem
{
    // Code not shown.
}
<DataContract()> _
Public Class LibraryPatron
    <DataMember()> _
    Public borrowedItems() As LibraryItem
End Class

<DataContract()> _
Public Class LibraryItem
    ' Code not shown.
End Class

<DataContract()> _
Public Class Book
    Inherits LibraryItem
    ' Code not shown.
End Class

<DataContract()> _
Public Class Newspaper
    Inherits LibraryItem
    ' Code not shown.
End Class

knownTypes パラメーターを使用して、シリアライザーのインスタンスを作成するコードを次に示します。

// Create a serializer for the inherited types using the knownType parameter.
Type[] knownTypes = new Type[] { typeof(Book), typeof(Newspaper) };
DataContractSerializer dcs =
new DataContractSerializer(typeof(LibraryPatron), knownTypes);
// All types are known after construction.
' Create a serializer for the inherited types using the knownType parameter.
Dim knownTypes() As Type = {GetType(Book), GetType(Newspaper)}
Dim dcs As New DataContractSerializer(GetType(LibraryPatron), knownTypes)
' All types are known after construction.

既定のルート名と名前空間の指定

通常、オブジェクトをシリアル化すると、データ コントラクト名と名前空間に従って、最も外側にある XML 要素の既定の名前と名前空間が決定されます。 内側のすべての要素の名前はデータ メンバー名から決定され、名前空間にはデータ コントラクトの名前空間が使用されます。 Name クラスと Namespace クラスのコンストラクターで、 DataContractAttribute および DataMemberAttribute の値を設定する例を次に示します。

[DataContract(Name = "PersonContract", Namespace = "http://schemas.contoso.com")]
public class Person2
{
    [DataMember(Name = "AddressMember")]
    public Address theAddress;
}

[DataContract(Name = "AddressContract", Namespace = "http://schemas.contoso.com")]
public class Address
{
    [DataMember(Name = "StreetMember")]
    public string street;
}
<DataContract(Name:="PersonContract", [Namespace]:="http://schemas.contoso.com")> _
Public Class Person2
    <DataMember(Name:="AddressMember")> _
    Public theAddress As Address
End Class

<DataContract(Name:="AddressContract", [Namespace]:="http://schemas.contoso.com")> _
Public Class Address
    <DataMember(Name:="StreetMember")> _
    Public street As String
End Class

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

<PersonContract xmlns="http://schemas.contoso.com">  
  <AddressMember>  
    <StreetMember>123 Main Street</StreetMember>  
   </AddressMember>  
</PersonContract>  

ただし、 rootName パラメーターと rootNamespace パラメーターの値を DataContractSerializer のコンストラクターに渡すことにより、ルート要素の既定の名前と名前空間をカスタマイズできます。 rootNamespace は、データ メンバーに対応する格納されている要素の名前空間には影響を及ぼしません。 このパラメーターの影響を受けるのは、最も外側の要素の名前空間だけです。

これらの値を文字列または XmlDictionaryString クラスのインスタンスとして渡すと、バイナリ XML 形式を使用して最適化できます。

オブジェクトの最大クォータの設定

DataContractSerializer の一部のコンストラクター オーバーロードには、 maxItemsInObjectGraph パラメーターが含まれています。 このパラメーターにより、 ReadObject メソッドの 1 回の呼び出しで、シリアライザーがシリアル化または逆シリアル化するオブジェクトの最大数が決まります (このメソッドは常に、1 つのルート オブジェクトを読み取りますが、このオブジェクトはそのデータ メンバー内に他のオブジェクトを保持する場合があります。さらに、それらのオブジェクトも他のオブジェクトを持つ場合があり、それ以降のオブジェクトについても同様です)。既定値は 65536 です。 配列のシリアル化または逆シリアル化を行う場合、すべての配列エントリが個別のオブジェクトとしてカウントされることに注意してください。 また、オブジェクトによってはメモリ表現が大きくなる場合があり、このクォータだけでは、サービス拒否攻撃の防止には不十分である可能性があることに注意してください。 詳細については、「セキュリティに関するデータの考慮事項」をご覧ください。 このクォータはデータの読み取り時と書き込み時の両方に適用されるため、このクォータに既定値を上回る値を設定する必要がある場合は、送信側 (シリアル化) と受信側 (逆シリアル化) の両方で設定することが重要です。

ラウンド トリップ

ラウンド トリップ は、1 つの操作でオブジェクトの逆シリアル化と再シリアル化が行われるときに発生します。 したがって、XML からオブジェクト インスタンスを経由し、再び XML ストリームに戻るラウンド トリップが発生します。

DataContractSerializer の一部のコンストラクター オーバーロードには、 ignoreExtensionDataObject パラメーターが含まれており、既定で false に設定されています。 この既定のモードでは、データ コントラクトが IExtensibleDataObject インターフェイスを実装していれば、データ コントラクトの新しいバージョンから以前のバージョンを経由し、新しいバージョンに戻るラウンド トリップで、データを失うことなく送信できます。 たとえば、 Person データ コントラクトのバージョン 1 に、 Name および PhoneNumber の各データ メンバーが含まれており、バージョン 2 で Nickname メンバーを追加したとします。 IExtensibleDataObject を実装している場合、バージョン 2 からバージョン 1 に情報を送信すると、 Nickname データが格納され、データを再度シリアル化したときに再出力されます。したがって、ラウンド トリップでデータが失われることはありません。 詳細については、「上位互換性のあるデータ コントラクト」と「データ コントラクトのバージョン管理」を参照してください。

ラウンド トリップでのセキュリティとスキーマ検証の問題

ラウンド トリップは、セキュリティに影響する場合があります。 たとえば、大量の無関係のデータを逆シリアル化し格納した場合、セキュリティ リスクが生じる可能性があります。 特に、デジタル署名を伴う場合は、検証方法のないこのようなデータの再出力について、セキュリティの問題が発生することがあります。 たとえば、前のシナリオでは、バージョン 1 エンドポイントが、悪質なデータを含む Nickname 値に署名する可能性があります。 また、スキーマ検証の問題が発生することもあります。エンドポイントでは、余分な値を出力せずに、記述されたコントラクトに厳密に従ったデータを常に出力することが必要な場合があります。 前の例では、バージョン 1 エンドポイントのコントラクトで NamePhoneNumberだけを出力するよう指定されているときに、スキーマ検証を使用すると、余分な Nickname 値の出力によって検証が失敗します。

ラウンド トリップの有効化と無効化

ラウンド トリップを無効にする場合は、 IExtensibleDataObject インターフェイスを実装しないでください。 型を制御できない場合は、 ignoreExtensionDataObject パラメーターを true に設定することで、同じ効果を得ることができます。

オブジェクト グラフの保存

次のコードに示すように、通常、シリアライザーはオブジェクト ID に留意することはありません。

[DataContract]
public class PurchaseOrder
{
    [DataMember]
    public Address billTo;
    [DataMember]
    public Address shipTo;
}

[DataContract]
public class Address
{
    [DataMember]
    public string street;
}
<DataContract()> _
Public Class PurchaseOrder

    <DataMember()> _
    Public billTo As Address

    <DataMember()> _
    Public shipTo As Address

End Class

<DataContract()> _
Public Class Address

    <DataMember()> _
    Public street As String

End Class

発注書を作成するコードを次に示します。

// Construct a purchase order:
Address adr = new Address();
adr.street = "123 Main St.";
PurchaseOrder po = new PurchaseOrder();
po.billTo = adr;
po.shipTo = adr;
' Construct a purchase order:
Dim adr As New Address()
adr.street = "123 Main St."
Dim po As New PurchaseOrder()
po.billTo = adr
po.shipTo = adr

billTo フィールドと shipTo フィールドが、同じオブジェクト インスタンスに設定されていることに注意してください。 ただし、生成される XML は重複する情報を繰り返します。XML は次のようになります。

<PurchaseOrder>  
  <billTo><street>123 Main St.</street></billTo>  
  <shipTo><street>123 Main St.</street></shipTo>  
</PurchaseOrder>  

この方法には以下の特性があり、望ましくないことがあります。

  • パフォーマンス。 データのレプリケートは非効率的です。

  • 循環参照。 他のオブジェクトを介してであっても、オブジェクトがそれ自体を参照している場合、レプリケーションによるシリアル化は無限ループを発生させます (この状況が発生した場合、シリアライザーは SerializationException をスローします)。

  • セマンティクス。 2 つの参照の参照先が 1 つのオブジェクトであり、2 つの同一のオブジェクトではない状態を維持することが重要な場合があります。

上記の理由から、 DataContractSerializer の一部のコンストラクター オーバーロードには、 preserveObjectReferences パラメーターが含まれています (既定値は falseです)。 このパラメーターを true に設定すると、オブジェクト参照をエンコードする特殊なメソッドが使用されます。これは、WCF のみに認識されるメソッドです。 trueに設定すると、XML コードの例は次のようになります。

<PurchaseOrder ser:id="1">  
  <billTo ser:id="2"><street ser:id="3">123 Main St.</street></billTo>  
  <shipTo ser:ref="2"/>  
</PurchaseOrder>  

"ser" 名前空間とは、シリアル化標準名前空間である http://schemas.microsoft.com/2003/10/Serialization/ を指します。 データの各部分は 1 回だけシリアル化され、ID 番号が与えられます。以降は、既にシリアル化されたデータへの参照を使用することになります。

重要

"id" および "ref" 属性の両方がデータ コントラクト XMLElementに存在する場合、"ref" 属性が使用され、"id" 属性は無視されます。

このモードの以下の制限を理解しておくことが重要です。

  • DataContractSerializerpreserveObjectReferences に設定された true によって生成した XML は、他のテクノロジと相互運用できません。この XML にアクセスできるのは、 DataContractSerializerpreserveObjectReferences に設定された別の trueインスタンスだけです。

  • この機能では、メタデータ (スキーマ) はサポートされていません。 生成されるスキーマは、 preserveObjectReferencesfalseに設定されている場合にのみ有効です。

  • この機能により、シリアル化および逆シリアル化プロセスの実行速度が低下することがあります。 データをレプリケートする必要はありませんが、このモードではオブジェクトの比較を追加で実行する必要があります。

注意事項

preserveObjectReferences モードを有効にする場合、 maxItemsInObjectGraph の値を適切なクォータに設定することが特に重要となります。 このモードでの配列の処理方法に起因して、攻撃者は maxItemsInObjectGraph のクォータによってのみ制限される、メモリを大量に消費させる小さい悪質なメッセージを容易に作成できます。

データ コントラクト サロゲートの指定

DataContractSerializer の一部のコンストラクター オーバーロードには、 dataContractSurrogate パラメーターが含まれています。このパラメーターは、 nullに設定できます。 それ以外の場合は、このパラメーターを使用して、 データ コントラクト サロゲートを指定できます。データ コントラクト サロゲートは、 IDataContractSurrogate インターフェイスを実装する型です。 このインターフェイスを使用して、シリアル化および逆シリアル化プロセスをカスタマイズできます。 詳細については、「データ コントラクト サロゲート」を参照してください。

シリアル化

次の情報は XmlObjectSerializerを継承するすべてのクラス ( DataContractSerializer クラスおよび NetDataContractSerializer クラスを含む) に適用されます。

単純なシリアル化

オブジェクトをシリアル化する最も簡単な方法は、オブジェクトを WriteObject メソッドに渡すことです。 このメソッドには 3 つのオーバーロードがあり、それぞれ StreamXmlWriter、および XmlDictionaryWriterへの書き込みに対応しています。 Stream オーバーロードの場合、出力は UTF-8 エンコードの XML です。 XmlDictionaryWriter オーバーロードを使用すると、シリアライザーによってバイナリ XML の出力が最適化されます。

WriteObject メソッドを使用した場合、シリアライザーはラッパー要素の既定の名前と名前空間を使用し、コンテンツと共に書き込みます (前の「既定のルート名と名前空間の指定」セクションを参照してください)。

XmlDictionaryWriterを使用した書き込みの例を次に示します。

Person p = new Person();
DataContractSerializer dcs =
    new DataContractSerializer(typeof(Person));
XmlDictionaryWriter xdw =
    XmlDictionaryWriter.CreateTextWriter(someStream,Encoding.UTF8 );
dcs.WriteObject(xdw, p);
Dim p As New Person()
Dim dcs As New DataContractSerializer(GetType(Person))
Dim xdw As XmlDictionaryWriter = _
    XmlDictionaryWriter.CreateTextWriter(someStream, Encoding.UTF8)
dcs.WriteObject(xdw, p)

これにより作成される XML は、次のようになります。

<Person>  
  <Name>Jay Hamlin</Name>  
  <Address>123 Main St.</Address>  
</Person>  

段階的なシリアル化

終了要素を書き込み、オブジェクトの内容を書き込み、ラッパー要素を閉じるには、それぞれ WriteStartObjectWriteObjectContentWriteEndObject の各メソッドを使用します。

Note

これらのメソッドの Stream オーバーロードはありません。

この段階的なシリアル化には、2 つの一般的な使用方法があります。 次の例に示すように、1 つは属性やコメントなどのコンテンツを WriteStartObjectWriteObjectContentの間に挿入する場合に使用します。

dcs.WriteStartObject(xdw, p);
xdw.WriteAttributeString("serializedBy", "myCode");
dcs.WriteObjectContent(xdw, p);
dcs.WriteEndObject(xdw);
dcs.WriteStartObject(xdw, p)
xdw.WriteAttributeString("serializedBy", "myCode")
dcs.WriteObjectContent(xdw, p)
dcs.WriteEndObject(xdw)

これにより作成される XML は、次のようになります。

<Person serializedBy="myCode">  
  <Name>Jay Hamlin</Name>  
  <Address>123 Main St.</Address>  
</Person>  

もう 1 つは、次のコードに示すように、 WriteStartObjectWriteEndObject を使用せずに、独自のカスタム ラッパー要素を書き込む場合 (ラッパーの書き込みを省略する場合もあります) に使用します。

xdw.WriteStartElement("MyCustomWrapper");
dcs.WriteObjectContent(xdw, p);
xdw.WriteEndElement();
xdw.WriteStartElement("MyCustomWrapper")
dcs.WriteObjectContent(xdw, p)
xdw.WriteEndElement()

これにより作成される XML は、次のようになります。

<MyCustomWrapper>  
  <Name>Jay Hamlin</Name>  
  <Address>123 Main St.</Address>  
</MyCustomWrapper>  

Note

段階的なシリアル化を使用すると、スキーマが無効な XML が生成されることがあります。

逆シリアル化

次の情報は XmlObjectSerializerを継承するすべてのクラス ( DataContractSerializer クラスおよび NetDataContractSerializer クラスを含む) に適用されます。

オブジェクトを逆シリアル化する最も簡単な方法は、 ReadObject メソッド オーバーロードのいずれかを呼び出すことです。 3 つのオーバーロードがあり、それぞれ XmlDictionaryReaderXmlReader、および Streamを使用した読み取りに対応しています。 Stream オーバーロードは、クォータによって保護されていないテキスト形式の XmlDictionaryReader を作成するため、信頼されたデータを読み取る場合にのみ使用します。

ReadObject メソッドが返すオブジェクトは、適切な型にキャストする必要があります。

DataContractSerializer のインスタンスと XmlDictionaryReaderを作成し、 Person インスタンスを逆シリアル化するコードを次に示します。

DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
FileStream fs = new FileStream(path, FileMode.Open);
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());

Person p = (Person)dcs.ReadObject(reader);
Dim dcs As New DataContractSerializer(GetType(Person))
Dim fs As New FileStream(path, FileMode.Open)
Dim reader As XmlDictionaryReader = _
   XmlDictionaryReader.CreateTextReader(fs, New XmlDictionaryReaderQuotas())

Dim p As Person = CType(dcs.ReadObject(reader), Person)

ReadObject メソッドを呼び出す前に、ラッパー要素またはラッパー要素の前にあるコンテンツ ノード以外のノードに XML リーダーを配置します。 これを行うには、次のコードに示すように、 Read またはその派生クラスの XmlReader メソッドを呼び出し、 NodeTypeを調べます。

DataContractSerializer ser = new DataContractSerializer(typeof(Person),
"Customer", @"http://www.contoso.com");
FileStream fs = new FileStream(path, FileMode.Open);
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
while (reader.Read())
{
    switch (reader.NodeType)
    {
        case XmlNodeType.Element:
            if (ser.IsStartObject(reader))
            {
                Console.WriteLine("Found the element");
                Person p = (Person)ser.ReadObject(reader);
                Console.WriteLine("{0} {1}    id:{2}",
                    p.Name , p.Address);
            }
            Console.WriteLine(reader.Name);
            break;
    }
}
Dim ser As New DataContractSerializer(GetType(Person), "Customer", "http://www.contoso.com")
Dim fs As New FileStream(path, FileMode.Open)
Dim reader As XmlDictionaryReader = XmlDictionaryReader.CreateTextReader(fs, New XmlDictionaryReaderQuotas())

While reader.Read()
    Select Case reader.NodeType
        Case XmlNodeType.Element
            If ser.IsStartObject(reader) Then
                Console.WriteLine("Found the element")
                Dim p As Person = CType(ser.ReadObject(reader), Person)
                Console.WriteLine("{0} {1}", _
                                   p.Name, p.Address)
            End If
            Console.WriteLine(reader.Name)
    End Select
End While

ReadObjectにリーダーを渡す前に、このラッパー要素の属性を読み取ることができます。

簡単な ReadObject オーバーロードのいずれかを使用すると、デシリアライザーはラッパー要素の既定の名前と名前空間を検索し (前の「既定のルート名と名前空間の指定」セクションを参照)、不明な要素が見つかった場合は例外をスローします。 前の例では、 <Person> ラッパー要素が必要とされます。 予想どおりの名前が付けられた要素にリーダーが配置されているかどうかを確認するために、 IsStartObject メソッドが呼び出されます。

ラッパー要素のこの名前チェックを無効にする方法があります。 ReadObject メソッドの一部のオーバーロードは、ブール型パラメーター verifyObjectNameを取得します。このパラメーターは、既定で true に設定されています。 このパラメーターを falseに設定すると、ラッパー要素の名前と名前空間が無視されます。 これは、前述の段階的なシリアル化機構を使用して書き込まれた XML を読み取る際に役立ちます。

NetDataContractSerializer の使用

DataContractSerializerNetDataContractSerializer の主な違いは、 DataContractSerializer がデータ コントラクト名を使用するのに対し、 NetDataContractSerializer は、シリアル化された XML に .NET Framework アセンブリと型の完全名を出力するという点です。 これは、シリアル化エンドポイントと逆シリアル化エンドポイント間で、まったく同じ型を共有する必要があることを意味します。 逆シリアル化する正確な型が常にわかっているため、 NetDataContractSerializer では既知の型機構は必要ないということです。

ただし、次のようないくつかの問題が発生する可能性があります。

  • セキュリティ。 逆シリアル化する XML で見つかったすべての型が読み込まれます。 これを利用して、悪質な型が強制的に読み込まれるおそれがあります。 信頼できないデータでの NetDataContractSerializer の使用は、( プロパティまたはコンストラクター パラメーターを使用して) シリアル化バインダー Binder を使用する場合に限定する必要があります。 バインダーが読み込みを許可するのは安全な型だけです。 このバインダー機構は、 System.Runtime.Serialization 名前空間の型が使用するものと同じです。

  • バージョン管理。 XML で型とアセンブリの完全名を使用する場合、型をバージョン管理する方法が厳しく制限されます。 型名、名前空間、アセンブリ名、およびアセンブリのバージョンを変更することはできません。 AssemblyFormat プロパティまたはコンストラクター パラメーターを既定値の Simple ではなく、 Full に設定すると、アセンブリのバージョンを変更できるようになりますが、ジェネリック パラメーターの型を変更することはできません。

  • 相互運用性。 .NET Framework 型名およびアセンブリ名は XML に含まれるため、 .NET Framework 以外のプラットフォームでは、生成されたデータにアクセスできません。

  • パフォーマンス。 型名とアセンブリ名を書き込むと、生成される XML のサイズが大幅に増加します。

この機構は、.NET Framework リモート処理で使用されるバイナリ シリアル化または SOAP シリアル化 (具体的には、BinaryFormatterSoapFormatter) に似ています。

NetDataContractSerializer の使用方法と DataContractSerializerの使用方法は似ていますが、次のような違いがあります。

  • コンストラクターでルート型を指定する必要はありません。 NetDataContractSerializerの同じインスタンスを使用して、すべての型をシリアル化できます。

  • コンストラクターは、既知の型のリストを受け入れません。 型名を XML にシリアル化する場合、既知の型機構は不要です。

  • コンストラクターは、データ コントラクト サロゲートを受け入れません。 代わりに、( ISurrogateSelector プロパティに割り当てられた) surrogateSelector という SurrogateSelector のパラメーターを受け入れます。 これは、従来のサロゲート機構です。

  • コンストラクターは、 assemblyFormat プロパティに割り当てられた、 FormatterAssemblyStyleAssemblyFormat というパラメーターを受け入れます。 前述のように、このパラメーターを使用することで、シリアライザーのバージョン管理機能を強化できます。 これは、バイナリ シリアル化または SOAP シリアル化の FormatterAssemblyStyle 機構と同じです。

  • コンストラクターは、 StreamingContext プロパティに割り当てられた context という Context のパラメーターを受け入れます。 このパラメーターを使用して、シリアル化する型に情報を渡すことができます。 この使用方法は、他の StreamingContext クラスで使用する System.Runtime.Serialization 機構と同じです。

  • Serialize メソッドと Deserialize メソッドは、 WriteObject メソッドと ReadObject メソッドのエイリアスです。 これらのメソッドは、より一貫性のあるプログラミング モデルで、バイナリ シリアル化または SOAP シリアル化を使用できるようにするために存在しています。

これらの機能の詳細については、「バイナリ シリアル化」を参照してください。

通常、 NetDataContractSerializerDataContractSerializer が使用する XML 形式には互換性がありません。 したがって、これらのシリアライザーの一方を使用してシリアル化し、もう一方を使用して逆シリアル化するシナリオはサポートされていません。

また、NetDataContractSerializer は、オブジェクト グラフの各ノードについて、完全な .NET Framework 型名およびアセンブリ名を出力しません。 この情報を出力するのは、情報が不明確な場合だけです。 つまり、ポリモーフィックである場合に、ルート オブジェクト レベルで出力します。

関連項目