次の方法で共有


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

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

.NET Framework オブジェクトをシリアル化する場合、シリアライザーは、新しい データ コントラクト モデルなど、さまざまなシリアル化プログラミング モデルを理解します。 サポートされている型の完全な一覧については、「 データ コントラクト シリアライザーでサポートされる型」を参照してください。 データ コントラクトの概要については、「データ コントラクトの使用」を参照してください。

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

WCF には、コンパニオン シリアライザー ( NetDataContractSerializer) も含まれています。 NetDataContractSerializer:

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

DataContractSerializerNetDataContractSerializerの両方が、共通の基底クラスであるXmlObjectSerializerから派生します。

Warnung

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

このコードは、Person クラスのインスタンスをシリアル化または逆シリアル化するためにのみ使用できるDataContractSerializerのインスタンスを構築します。

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 パラメーターを使用して、使用可能な既知の型の一覧をシリアライザーのコンストラクターに渡す必要があります。 既知の型の詳細については、「 データ コントラクトの既知の型」を参照してください

次の例は、特定の型のコレクションであるLibraryItemを含むクラス (LibraryPatron) を示しています。 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 要素の既定の名前と名前空間は、データ コントラクトの名前と名前空間に従って決定されます。 すべての内部要素の名前はデータ メンバー名から決定され、その名前空間はデータ コントラクトの名前空間です。 次の例では、DataContractAttribute クラスと DataMemberAttribute クラスのコンストラクターにName値とNamespace値を設定します。

[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は、データ メンバーに対応する包含要素の名前空間には影響しないことに注意してください。 最も外側の要素の名前空間にのみ影響します。

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

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

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

ラウンド トリップ

ラウンド トリップは、オブジェクトが逆シリアル化され、1 回の操作で再シリアル化されるときに発生します。 したがって、XML からオブジェクト インスタンスに戻り、もう一度 XML ストリームに戻ります。

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

ラウンド トリップに関するセキュリティとスキーマの有効性に関する問題

ラウンド トリップはセキュリティに影響を与える可能性があります。 たとえば、大量の余分なデータを逆シリアル化して格納すると、セキュリティ上のリスクが生じる可能性があります。 特にデジタル署名が関係している場合は、検証する方法がないことを、このデータの再出力に関するセキュリティ上の懸念がある可能性があります。 たとえば、前のシナリオでは、バージョン 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 つの参照が 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 番号が与えられ、それ以降の使用により、既にシリアル化されたデータへの参照が生成されます。

Von Bedeutung

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

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

  • DataContractSerializerが生成する XML は、preserveObjectReferencestrue に設定しても他のテクノロジと相互運用できず、別のDataContractSerializer インスタンスでのみアクセスでき、preserveObjectReferencestrue に設定されています。

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

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

注意事項

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

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

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

シリアル化

次の情報は、DataContractSerializerクラスやNetDataContractSerializer クラスなど、XmlObjectSerializerから継承するすべてのクラスに適用されます。

単純なシリアル化

オブジェクトをシリアル化する最も基本的な方法は、 WriteObject メソッドに渡すことです。 StreamXmlWriter、またはXmlDictionaryWriterに書き込むための 3 つのオーバーロードがあります。 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>  

ステップ-By-Step シリアル化

WriteStartObjectWriteObjectContent、およびWriteEndObjectメソッドを使用して、終了要素を書き込み、オブジェクトの内容を書き込み、ラッパー要素をそれぞれ閉じます。

これらのメソッドの 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>  

ステップ バイ ステップのシリアル化を使用すると、スキーマが無効な XML になる可能性があります。

逆シリアル化

次の情報は、DataContractSerializerクラスやNetDataContractSerializer クラスなど、XmlObjectSerializerから継承するすべてのクラスに適用されます。

オブジェクトを逆シリアル化する最も基本的な方法は、 ReadObject メソッドのオーバーロードのいずれかを呼び出す方法です。 3 つのオーバーロードがあり、それぞれが XmlDictionaryReaderXmlReader、または Streamを使用して読み取ります。 Streamオーバーロードは、クォータによって保護されていないテキスト XmlDictionaryReaderを作成し、信頼できるデータの読み取りにのみ使用する必要があることに注意してください。

また、 ReadObject メソッドが返すオブジェクトは、適切な型にキャストする必要があることにも注意してください。

次のコードは、 DataContractSerializerXmlDictionaryReaderのインスタンスを構築し、 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 リーダーを配置します。 これを行うには、次のコードに示すように、XmlReaderまたはその派生のRead メソッドを呼び出し、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($"{p.Name} {p.Address}    id:{2}");
            }
            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 メソッドのいくつかのオーバーロードは、既定でtrueに設定されているブール型パラメーター verifyObjectNameを受け取ります。 falseに設定すると、ラッパー要素の名前と名前空間は無視されます。 これは、前に説明したステップ バイ ステップのシリアル化メカニズムを使用して記述された XML を読み取る場合に便利です。

NetDataContractSerializer の使用

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

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

  • セキュリティ。 逆シリアル化されている XML で見つかったすべての型が読み込まれます。 これは、悪意のある型の読み込みを強制するために悪用される可能性があります。 信頼されていないデータで NetDataContractSerializer を使用する場合は、 シリアル化バインダー が使用されている場合にのみ行う必要があります ( Binder プロパティまたはコンストラクター パラメーターを使用します)。 バインダーは、安全な型のみを読み込むことができます。 Binder メカニズムは、 System.Runtime.Serialization 名前空間で使用される型と同じです。

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

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

  • 性能 型とアセンブリ名を書き出す場合、結果の XML のサイズが大幅に増加します。

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

NetDataContractSerializerの使用は、DataContractSerializerの使用と似ていますが、次の違いがあります。

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

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

  • コンストラクターは、データ コントラクトサロゲートを受け入れません。 代わりに、surrogateSelector (SurrogateSelector プロパティにマップされる) と呼ばれるISurrogateSelector パラメーターを受け取ります。 これは従来のサロゲート メカニズムです。

  • コンストラクターは、AssemblyFormat プロパティにマップするFormatterAssemblyStyleassemblyFormatというパラメーターを受け取ります。 前述のように、これはシリアライザーのバージョン管理機能を強化するために使用できます。 これは、バイナリまたは SOAP シリアル化の FormatterAssemblyStyle メカニズムと同じです。

  • コンストラクターは、Context プロパティにマップする context と呼ばれるStreamingContext パラメーターを受け取ります。 これを使用して、シリアル化される型に情報を渡すことができます。 この使用法は、他のSystem.Runtime.Serialization クラスで使用されるStreamingContext メカニズムと同じです。

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

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

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

また、 NetDataContractSerializer では、オブジェクト グラフ内の各ノードの完全な .NET Framework 型とアセンブリ名は出力されないことに注意してください。 その情報は、あいまいな場合にのみ出力されます。 つまり、ルート オブジェクト レベルで出力され、ポリモーフィックなケースに対して出力されます。

こちらも参照ください