データ コントラクトの XML および ADO.NET の種類XML and ADO.NET Types in Data Contracts

Windows Communication Foundation (WCF) のデータ コントラクト モデルでは、XML を直接表す特定の種類をサポートします。The Windows Communication Foundation (WCF) data contract model supports certain types that represent XML directly. シリアライザーは、これらの型を XML にシリアル化するとき、型の XML コンテンツを書き出しますが、それ以上の処理は行いません。When these types are serialized to XML, the serializer writes out the XML contents of these types without any further processing. サポートされている型は、XmlElementXmlNode の配列 (XmlNode 型自体はサポートされていません)、および IXmlSerializable を実装した型です。Supported types are XmlElement, arrays of XmlNode (but not the XmlNode type itself), as well as types that implement IXmlSerializable. データベース プログラミングでは、DataSet 型、DataTable 型、および型指定されたデータセットが一般的に使用されます。The DataSet and DataTable type, as well as typed datasets, are commonly used in database programming. これらの型は IXmlSerializable インターフェイスを実装するので、データ コントラクト モデルでシリアル化可能です。These types implement the IXmlSerializable interface and are therefore serializable in the data contract model. この型に関する考慮事項について、このトピックの最後に説明します。Some special considerations for these types are listed at the end of this topic.

XML 型XML Types

XmlElementXml Element

XmlElement 型は、その XML コンテンツを使用してシリアル化されます。The XmlElement type is serialized using its XML contents. たとえば、次の型を使用するとします。For example, using the following type.

[DataContract(Namespace=@"http://schemas.contoso.com")]
public class MyDataContract
{
    [DataMember]
    public XmlElement myDataMember;
    public void TestClass()
    {
        XmlDocument xd = new XmlDocument();
        myDataMember = xd.CreateElement("myElement");
        myDataMember.InnerText = "myContents";
        myDataMember.SetAttribute
         ("myAttribute","myValue");
    }
}
<DataContract([Namespace] := "http://schemas.contoso.com")>  _
Public Class MyDataContract
    <DataMember()>  _
    Public myDataMember As XmlElement
    
    Public Sub TestClass() 
        Dim xd As New XmlDocument()
        myDataMember = xd.CreateElement("myElement")
        myDataMember.InnerText = "myContents"
        myDataMember.SetAttribute("myAttribute", "myValue")
    
    End Sub 
End Class 

これは、次のように XML にシリアル化されます。This is serialized to XML as follows:

<MyDataContract xmlns="http://schemas.contoso.com">  
    <myDataMember>  
        <myElement xmlns="" myAttribute="myValue">  
            myContents  
        </myElement>  
    </myDataMember>  
</MyDataContract>  

ラッパー データ メンバー要素 <myDataMember> が引き続き存在している点に注意してください。Notice that a wrapper data member element <myDataMember> is still present. データ コントラクト モデルにはこの要素を削除する方法がありません。There is no way of removing this element in the data contract model. このモデルを処理するシリアライザー (DataContractSerializerNetDataContractSerializer) では、このラッパー要素に特別な属性が出力されることがあります。The serializers that handle this model (the DataContractSerializer and NetDataContractSerializer) may emit special attributes into this wrapper element. この特別な属性には、標準の XML スキーマ インスタンスの "nil" 属性 (XmlElementnull に設定できるようにする属性) や "type" 属性 (XmlElement をポリモーフィックに使用できるようにする属性) などがあります。These attributes include the standard XML Schema Instance "nil" attribute (allowing the XmlElement to be null) and the "type" attribute (allowing XmlElement to be used polymorphically). また、次の XML 属性は、WCF に固有します。"Id"、"Ref"、"Type"および"Assembly"です。Also, the following XML attributes are specific to WCF: "Id", "Ref", "Type" and "Assembly". これらの属性が出力されるのは、オブジェクト グラフの保存モードを有効にするか XmlElement を使用する場合に NetDataContractSerializer をサポートするためです These attributes may be emitted to support using the XmlElement with the object graph preservation mode enabled, or with the NetDataContractSerializer. (オブジェクト グラフの保存モードの詳細については、次を参照してくださいシリアル化および逆シリアル化。)。(For more information about the object graph preservation mode, see Serialization and Deserialization.)

XmlElement の配列またはコレクションを使用できます。これらは、他の配列またはコレクションとして処理されます。Arrays or collections of XmlElement are allowed and are handled as any other array or collection. つまり、コレクション全体のラッパー要素と、配列に含まれる <myDataMember> ごとに個別のラッパー要素 (上記の例の XmlElement と同様) が存在することになります。That is, there is a wrapper element for the entire collection, and a separate wrapper element (similar to <myDataMember> in the preceding example) for each XmlElement in the array.

逆シリアル化時には、デシリアライザーによって受信 XML から XmlElement が作成されます。On deserialization, an XmlElement is created by the deserializer from the incoming XML. 有効な親 XmlDocument は、デシリアライザーによって提供されます。A valid parent XmlDocument is provided by the deserializer.

XmlElement に逆シリアル化される XML フラグメントでは、先祖要素のプレフィックス定義に依存するのではなく、使用するすべてのプレフィックスを定義しておく必要があります。Make sure that the XML fragment that is deserialized to an XmlElement defines all prefixes that it uses and does not rely on any prefix definitions from ancestor elements. これは、DataContractSerializer を使用して、DataContractSerializer 以外の別のソースから XML にアクセスする場合にのみ考慮する必要があります。This is a concern only when using the DataContractSerializer to access XML from a different (non-DataContractSerializer) source.

使用すると、 DataContractSerializerXmlElement型のデータ メンバーにのみ、ポリモーフィックに割り当てることがObjectします。When used with the DataContractSerializer, the XmlElement may be assigned polymorphically, but only to a data member of type Object. IEnumerable が実装されていても、XmlElement をコレクション型として使用したり、IEnumerable データ メンバーに割り当てることはできません。Even though it implements IEnumerable, an XmlElement cannot be used as a collection type and cannot be assigned to an IEnumerable data member. すべてのポリモーフィックな割り当てと同様、DataContractSerializerデータ コントラクト名を出力 – 結果の XML にこの例では、"XmlElement"になって、"http://schemas.datacontract.org/2004/07/System.Xml"名前空間。As with all polymorphic assignments, the DataContractSerializer emits the data contract name in the resulting XML – in this case, it is "XmlElement" in the "http://schemas.datacontract.org/2004/07/System.Xml" namespace.

NetDataContractSerializer を使用する場合、XmlElement の有効なポリモーフィック割り当て (Object または IEnumerable への割り当て) がすべてサポートされます。With the NetDataContractSerializer, any valid polymorphic assignment of XmlElement (to Object or IEnumerable) is supported.

XmlElement から派生した型がポリモーフィックに割り当てられているかどうかに関係なく、このような型と上記の 2 つのシリアライザーを一緒に使用しないでください。Do not attempt to use either of the serializers with types derived from XmlElement, whether they are assigned polymorphically or not.

XmlNode の配列Array of XmlNode

XmlNode の配列の使用は、XmlElement の使用に非常に似ています。Using arrays of XmlNode is very similar to using XmlElement. XmlNode の配列を使用すると、XmlElement を使用する場合よりも高い柔軟性が得られます。Using arrays of XmlNode gives you more flexibility than using XmlElement. たとえば、データ メンバーがラップする要素内に複数の要素を作成できます。You can write multiple elements inside the data member wrapping element. データ メンバーがラップする要素内には、XML コメントなどの要素以外のコンテンツを挿入することもできます。You can also inject content other than elements inside of the data member wrapping element, such as XML comments. さらに、ラップする側のデータ メンバー要素にも属性を挿入できます。Finally, you can put attributes into the wrapping data member element. これらはすべて、XmlNode の配列に XmlNode の特定の派生クラス (XmlAttributeXmlElementXmlComment など) を追加することによって実現できます。All this can be achieved by populating the array of XmlNode with specific derived classes of XmlNode such as XmlAttribute, XmlElement or XmlComment. たとえば、次の型を使用するとします。For example, using the following type.

[DataContract(Namespace="http://schemas.contoso.com")]
public class MyDataContract
{
    [DataMember]
    public XmlNode[] myDataMember = new XmlNode[4];
    public void TestClass()
    {
        XmlDocument xd = new XmlDocument();
        XmlElement xe = xd.CreateElement("myElement");
        xe.InnerText = "myContents";
        xe.SetAttribute
         ("myAttribute","myValue");
      
        XmlAttribute atr = xe.Attributes[0];
        XmlComment cmnt = xd.CreateComment("myComment");
        
      myDataMember[0] = atr;
      myDataMember[1] = cmnt;
      myDataMember[2] = xe;
      myDataMember[3] = xe;
    }
}
<DataContract([Namespace] := "http://schemas.contoso.com")>  _
Public Class MyDataContract
    <DataMember()>  _
    Public myDataMember(3) As XmlNode
    
    Public Sub TestClass() 
        Dim xd As New XmlDocument()
        Dim xe As XmlElement = xd.CreateElement("myElement")
        xe.InnerText = "myContents"
        xe.SetAttribute("myAttribute", "myValue")
        
        Dim atr As XmlAttribute = xe.Attributes(0)
        Dim cmnt As XmlComment = xd.CreateComment("myComment")
        
        myDataMember(0) = atr
        myDataMember(1) = cmnt
        myDataMember(2) = xe
        myDataMember(3) = xe
    
    End Sub 
    
End Class 

シリアル化すると、生成される XML は次のコードのようになります。When serialized, the resulting XML is similar to the following code.

<MyDataContract xmlns="http://schemas.contoso.com">  
  <myDataMember myAttribute="myValue">  
     <!--myComment-->  
     <myElement xmlns="" myAttribute="myValue">  
 myContents  
     </myElement>  
     <myElement xmlns="" myAttribute="myValue">  
       myContents  
     </myElement>  
  </myDataMember>  
</MyDataContract>  

データ メンバー ラッパー要素 <myDataMember> には、1 つの属性、1 つのコメント、および 2 つの要素が含まれています。Note that the data member wrapper element <myDataMember> contains an attribute, a comment, and two elements. これらが、シリアル化された 4 つの XmlNode インスタンスです。These are the four XmlNode instances that were serialized.

結果的に無効な XML になる XmlNode の配列は、シリアル化できません。An array of XmlNode that results in invalid XML cannot be serialized. たとえば、最初のインスタンスが XmlNode で、次のインスタンスが XmlElement という 2 つの XmlAttribute インスタンスの配列は、無効です。このシーケンスは、有効な XML インスタンスに対応していません (属性を関連付ける場所がありません)。For example, an array of two XmlNode instances where the first one is an XmlElement and the second one is an XmlAttribute is invalid, because this sequence does not correspond to any valid XML instance (there is no place to attach the attribute to).

XmlNode の配列の逆シリアル化時には、ノードが作成され、そのノードに受信 XML からの情報が追加されます。On deserialization of an array of XmlNode, nodes are created and populated with information from the incoming XML. 有効な親 XmlDocument は、デシリアライザーによって提供されます。A valid parent XmlDocument is provided by the deserializer. すべてのノードが逆シリアル化、ラッパー データ メンバー要素の属性が、(ポリモーフィック割り当てを示すために使用する属性) などの WCF シリアライザーによって配置された属性を除外します。All nodes are deserialized, including any attributes on the wrapper data member element, but excluding the attributes placed there by the WCF serializers (such as the attributes used to indicate polymorphic assignment). XML フラグメントですべての名前空間プレフィックスを定義するときの注意点は、XmlNode の逆シリアル化に適用されるのと同様に、XmlElement の配列の逆シリアル化にも適用されます。The caveat about defining all namespace prefixes in the XML fragment applies to the deserialization of arrays of XmlNode just like it does to deserializing XmlElement.

オブジェクト グラフの保存を有効にしてシリアライザーを使用した場合、オブジェクトの等価性は、個別の XmlNode インスタンスではなく、XmlNode 配列のレベルでのみ保存されます。When using the serializers with object graph preservation turned on, object equality is only preserved on the level of XmlNode arrays, not individual XmlNode instances.

1 つ以上のノードが XmlNode に設定された null の配列をシリアル化しないようにしてください。Do not attempt to serialize an array of XmlNode where one or more of the nodes is set to null. 配列メンバー全体を null にすることはできますが、配列に格納された個々の XmlNode を null にすることはできません。It is permitted for the entire array member to be null, but not for any individual XmlNode contained in the array. 配列メンバー全体が null の場合、ラッパー データ メンバー要素には、配列メンバー全体が null であることを示す特別な属性が含まれます。If the entire array member is null, the wrapper data member element contains a special attribute that indicates that it is null. 逆シリアル化時にも、配列メンバー全体が null になります。On deserialization, the entire array member also becomes null.

XmlNode の正規の配列だけが、シリアライザーによって特別に処理されます。Only regular arrays of XmlNode are treated specially by the serializer. XmlNode を含む他のコレクション型として宣言されたデータ メンバーや、XmlNode から派生した型の配列として宣言されたデータ メンバーには、特別な処理は行われません。Data members declared as other collection types that contain XmlNode, or data members declared as arrays of types derived from XmlNode, are not treated specially. このため、これらのデータ メンバーは、シリアル化に関するその他の条件のいずれかを満たしている場合を除き、通常はシリアル化できません。Thus, they are normally not serializable unless they also meet one of the other criteria for serializing.

XmlNode の配列の配列またはコレクションを使用できます。Arrays or collections of arrays of XmlNode are allowed. コレクション全体のラッパー要素と、外側の配列またはコレクションに含まれる <myDataMember> の配列ごとに個別のラッパー要素 (上記の例の XmlNode と同様) が存在することになります。There is a wrapper element for the entire collection, and a separate wrapper element (similar to <myDataMember> in the preceding example) for each array of XmlNode in the outer array or collection.

ArrayObject または ArrayIEnumerable 型のデータ メンバーに XmlNode インスタンスを追加しても、そのデータ メンバーが Array インスタンスの XmlNode として扱われることはありません。Populating a data member of type Array of Object or Array of IEnumerable with XmlNode instances does not result in the data member being treated as an Array of XmlNode instances. 配列の各メンバーは個別にシリアル化されます。Each array member is serialized separately.

DataContractSerializer を使用する場合、XmlNode の配列をポリモーフィックに割り当てることができますが、その対象は Object 型のデータ メンバーだけです。When used with the DataContractSerializer, arrays of XmlNode can be assigned polymorphically, but only to a data member of type Object. IEnumerable が実装されていても、XmlNode の配列をコレクション型として使用したり、IEnumerable データ メンバーに割り当てることはできません。Even though it implements IEnumerable, an array of XmlNode cannot be used as a collection type and be assigned to an IEnumerable data member. すべてのポリモーフィックな割り当てと同様、DataContractSerializerデータ コントラクト名を出力"結果の XML にこの例では、ArrayOfXmlNode「です」で、"http://schemas.datacontract.org/2004/07/System.Xml"名前空間。As with all polymorphic assignments, the DataContractSerializer emits the data contract name in the resulting XML – in this case, it is "ArrayOfXmlNode" in the "http://schemas.datacontract.org/2004/07/System.Xml" namespace. 使用すると、NetDataContractSerializerの有効な割り当て、XmlNode配列はサポートされています。When used with the NetDataContractSerializer, any valid assignment of an XmlNode array is supported.

スキーマの考慮事項Schema Considerations

XML 型のスキーマ マッピングの詳細については、次を参照してください。 Data Contract Schema Referenceします。For details about the schema mapping of XML types, see Data Contract Schema Reference. ここでは、重要な点の概要について説明します。This section provides a summary of the important points.

XmlElement 型のデータ メンバーは、次の匿名型を使用して定義された要素にマップされます。A data member of type XmlElement is mapped to an element defined using the following anonymous type.

<xsd:complexType>  
   <xsd:sequence>  
      <xsd:any minOccurs="0" processContents="lax" />  
   </xsd:sequence>  
</xsd:complexType>  

XmlNode の Array 型のデータ メンバーは、次の匿名型を使用して定義された要素にマップされます。A data member of type Array of XmlNode is mapped to an element defined using the following anonymous type.

<xsd:complexType mixed="true">  
   <xsd:sequence>  
      <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax" />  
   </xsd:sequence>  
   <xsd:anyAttribute/>  
</xsd:complexType>  

IXmlSerializable インターフェイスを実装する型Types Implementing the IXmlSerializable Interface

IXmlSerializable インターフェイスを実装する型は、DataContractSerializer で完全にサポートされます。Types that implement the IXmlSerializable interface are fully supported by the DataContractSerializer. これらの型には、スキーマを制御するために必ず XmlSchemaProviderAttribute 属性を適用する必要があります。The XmlSchemaProviderAttribute attribute should always be applied to these types to control their schema.

IXmlSerializable を実装する型には、任意のコンテンツを表す型、1 つの要素を表す型、および従来の DataSet 型の 3 種類があります。There are three varieties of types that implement IXmlSerializable: types that represent arbitrary content, types that represent a single element, and legacy DataSet types.

  • コンテンツ型では、XmlSchemaProviderAttribute 属性によって指定されたスキーマ プロバイダー メソッドが使用されます。Content types use a schema provider method specified by the XmlSchemaProviderAttribute attribute. このメソッドから null が返されることはなく、属性の IsAny プロパティは既定値 false のままになります。The method does not return null, and the IsAny property on the attribute is left at its default value of false. これは、IXmlSerializable 型の最も一般的な使用方法です。This is the most common usage of IXmlSerializable types.

  • 要素型は、IXmlSerializable 型が自身のルート要素名を制御する必要があるときに使用します。Element types are used when an IXmlSerializable type must control its own root element name. 型を要素型としてマークするには、IsAny 属性の XmlSchemaProviderAttribute プロパティを true に設定するか、スキーマ プロバイダー メソッドから null を返します。To mark a type as an element type, either set the IsAny property on the XmlSchemaProviderAttribute attribute to true or return null from the schema provider method. スキーマ プロバイダー メソッドの使用は、要素型ではオプションです。XmlSchemaProviderAttribute でメソッド名の代わりに null を指定できます。Having a schema provider method is optional for element types – you may specify null instead of the method name in the XmlSchemaProviderAttribute. ただし、IsAnytrue で、スキーマ プロバイダー メソッドが指定されている場合、メソッドは null を返す必要があります。However, if IsAny is true and a schema provider method is specified, the method must return null.

  • 従来の DataSet 型は、IXmlSerializable 属性でマークされていない XmlSchemaProviderAttribute 型です。Legacy DataSet types are IXmlSerializable types that are not marked with the XmlSchemaProviderAttribute attribute. これらの型は、スキーマ生成に関して GetSchema メソッドに依存しています。Instead, they rely on the GetSchema method for schema generation. 以前のバージョンの .NET Framework では、このパターンが DataSet 型に使用され、型指定されたデータセットからクラスが派生されます。ただし、現在、このパターンは使用されなくなっており、従来の型に対応することだけを目的としてサポートされています。This pattern is used for the DataSet type and its typed dataset derives a class in earlier versions of the .NET Framework, but is now obsolete and is supported only for legacy reasons. このパターンに依存せず、必ず XmlSchemaProviderAttributeIXmlSerializable 型に適用してください。Do not rely on this pattern and always apply the XmlSchemaProviderAttribute to your IXmlSerializable types.

IXmlSerializable コンテンツ型IXmlSerializable Content Types

IXmlSerializable を実装しており、以前に定義したコンテンツ型である型のデータ メンバーをシリアル化すると、シリアライザーはそのデータ メンバーのラッパー要素を書き込み、WriteXml メソッドに制御を渡します。When serializing a data member of a type that implements IXmlSerializable and is a content type as defined previously, the serializer writes the wrapper element for the data member and pass control to the WriteXml method. WriteXml 実装により、ラッパー要素に属性が追加されるなど、任意の XML が書き込まれることがあります。The WriteXml implementation can write any XML, including adding attributes to the wrapper element. WriteXml の実行後、シリアライザーは要素を閉じます。After WriteXml is done, the serializer closes the element.

IXmlSerializable を実装しており、以前に定義したコンテンツ型である型のデータ メンバーを逆シリアル化すると、デシリアライザーはそのデータ メンバーのラッパー要素に XML リーダーを配置し、ReadXml メソッドに制御を渡します。When deserializing a data member of a type that implements IXmlSerializable and is a content type as defined previously, the deserializer positions the XML reader on the wrapper element for the data member and pass control to the ReadXml method. このメソッドは、開始タグと終了タグを含む、要素全体を読み取る必要があります。The method must read the entire element, including the start and end tags. ReadXml コードでは、要素が空の場合も忘れずに処理してください。Make sure your ReadXml code handles the case where the element is empty. また、ReadXml の実装では、特定の方法で名前が付けられたラッパー要素に依存しないようにしてください。Additionally, your ReadXml implementation should not rely on the wrapper element being named a particular way. シリアライザーによって選択される名前は、異なる場合があります。The name is chosen by the serializer can vary.

IXmlSerializable コンテンツ型は、たとえば Object 型のデータ メンバーなどに、ポリモーフィックに割り当てることができます。It is permitted to assign IXmlSerializable content types polymorphically, for example, to data members of type Object. また、型インスタンスを null にすることもできます。It is also permitted for the type instances to be null. さらに、IXmlSerializable 型は、オブジェクト グラフの保存を有効にして NetDataContractSerializer で使用することも可能です。Finally, it is possible to use IXmlSerializable types with object graph preservation enabled and with the NetDataContractSerializer. これらすべての機能が特定の属性をラッパー要素にアタッチする WCF のシリアライザーが必要です ("nil"と WCF 固有の名前空間で XML スキーマ インスタンス名前空間と"Id"、"Ref"、"Type"および"Assembly"で"type")。All these features require the WCF serializer to attach certain attributes into the wrapper element ("nil" and "type" in the XML Schema Instance namespace and "Id", "Ref", "Type" and "Assembly" in a WCF-specific namespace).

ReadXml を実装するときに無視する属性Attributes to Ignore when Implementing ReadXml

ReadXml コードに制御を渡す前に、デシリアライザーは、XML 要素を調べ、前述の特別な XML 属性を検出し、その属性に従って動作します。Before passing control to your ReadXml code, the deserializer examines the XML element, detects these special XML attributes, and acts on them. たとえば、"nil" が true の場合は、null 値が逆シリアル化され、ReadXml は呼び出されません。For example, if "nil" is true, a null value is deserialized and ReadXml is not called. ポリモーフィズムが検出された場合は、要素のコンテンツが別の型と同様に逆シリアル化されます。If polymorphism is detected, the contents of the element are deserialized as if it was a different type. ポリモーフィックに割り当てられた型の ReadXml 実装が呼び出されます。The polymorphically assigned type’s implementation of ReadXml is called. どの場合も、これらの特別な属性がデシリアライザーによって処理されるため、ReadXml 実装ではこれらの属性を無視する必要があります。In any case, a ReadXml implementation should ignore these special attributes because they are handled by the deserializer.

IXmlSerializable コンテンツ型のスキーマに関する考慮事項Schema Considerations for IXmlSerializable Content Types

IXmlSerializable コンテンツ型のスキーマをエクスポートすると、スキーマ プロバイダー メソッドが呼び出されます。When exporting schema an IXmlSerializable content type, the schema provider method is called. このスキーマ プロバイダー メソッドには、XmlSchemaSet が渡されます。An XmlSchemaSet is passed to the schema provider method. このメソッドは、有効なスキーマをスキーマ セットに追加できます。The method can add any valid schema to the schema set. スキーマ セットには、スキーマをエクスポートした時点で既に認識されていたスキーマが格納されます。The schema set contains the schema that is already known at the time when schema export occurs. スキーマ プロバイダー メソッドは、スキーマ セットに項目を追加する必要があるときに、適切な名前空間を持つ XmlSchema がそのセットに既に存在するかどうかを確認する必要があります。When the schema provider method must add an item to the schema set, it must determine if an XmlSchema with the appropriate namespace already exists in the set. 存在する場合、スキーマ プロバイダー メソッドは新しい項目を既存の XmlSchema に追加する必要があります。If it does, the schema provider method must add the new item to the existing XmlSchema. 存在しない場合、新しい XmlSchema インスタンスを作成する必要があります。Otherwise, it must create a new XmlSchema instance. これは、IXmlSerializable 型の配列を使用する場合に重要です。This is important if arrays of IXmlSerializable types are being used. たとえば、IXmlSerializable 型を名前空間 "B" の "A" 型としてエクスポートする場合、スキーマ プロバイダー メソッドが呼び出される前に、"B" が "ArrayOfA" 型を保持するためのスキーマがスキーマ セットに既に存在している可能性があります。For example, if you have an IXmlSerializable type that gets exported as type "A" in namespace "B", it is possible that by the time the schema provider method is called the schema set already contains the schema for "B" to hold the "ArrayOfA" type.

型を XmlSchemaSet に追加する以外に、コンテンツ型のスキーマ プロバイダー メソッドは null 以外の値を返す必要があります。In addition to adding types to the XmlSchemaSet, the schema provider method for content types must return a non-null value. このメソッドは、特定の XmlQualifiedName 型で使用するスキーマ型の名前を指定する IXmlSerializable を返すことができます。It can return an XmlQualifiedName that specifies the name of the schema type to use for the given IXmlSerializable type. この修飾名は、その型のデータ コントラクト名および名前空間としても使用されます。This qualified name also serves as the data contract name and namespace for the type. スキーマ プロバイダー メソッドは、スキーマ セットにまだ存在していない型であっても、復帰時に返すことができます。It is permitted to return a type that does not exist in the schema set immediately when the schema provider method returns. ただし、関連するすべての型がエクスポートされる (Export の関連するすべての型に対して XsdDataContractExporter メソッドが呼び出され、Schemas プロパティにアクセスする) までに、その型がスキーマ セットに存在している必要があります。However, it is expected that by the time all related types are exported (the Export method is called for all relevant types on the XsdDataContractExporter and the Schemas property is accessed), the type exists in the schema set. 関連するすべての Schemas 呼び出しが実行される前に Export プロパティにアクセスすると、XmlSchemaException が発生する可能性があります。Accessing the Schemas property before all relevant Export calls have been made can result in an XmlSchemaException. エクスポート プロセスの詳細については、次を参照してください。クラスからのスキーマのエクスポートします。For more information about the export process, see Exporting Schemas from Classes.

スキーマ プロバイダー メソッドは、使用する XmlSchemaType を返すこともできます。The schema provider method can also return the XmlSchemaType to use. その型は、匿名の場合とそうでない場合があります。The type may or may not be anonymous. 匿名の場合、IXmlSerializable 型のスキーマは、IXmlSerializable 型がデータ メンバーとして使用されるたびに匿名型としてエクスポートされます。If it is anonymous, the schema for the IXmlSerializable type is exported as an anonymous type every time the IXmlSerializable type is used as a data member. IXmlSerializable 型には、データ コントラクト名と名前空間が引き続き保持されます The IXmlSerializable type still has a data contract name and namespace. (これで説明されているように決定されますがData Contract Namesする点を除いて、DataContractAttribute属性を使用して、名前をカスタマイズすることはできません)。匿名でない場合、型は XmlSchemaSet に含まれている型のいずれかである必要があります。(This is determined as described in Data Contract Names except that the DataContractAttribute attribute cannot be used to customize the name.) If it is not anonymous, it must be one of the types in the XmlSchemaSet. これは、型の XmlQualifiedName を返す場合と同じです。This case is equivalent to returning the XmlQualifiedName of the type.

さらに、型のグローバル要素宣言がエクスポートされます。Additionally, a global element declaration is exported for the type. 型に XmlRootAttribute 属性が適用されていない場合、その要素にはデータ コントラクトと同じ名前と名前空間が使用され、その "nillable" プロパティは true に設定されます。If the type does not have the XmlRootAttribute attribute applied to it, the element has the same name and namespace as the data contract, and its "nillable" property is true. 唯一の例外は、スキーマ名前空間 ("http://www.w3.org/2001/XMLSchema")-スキーマの名前空間に新しい要素を追加することが禁止されているために、対応するグローバル要素が空白の名前空間は、型のデータ コントラクトがこの名前空間にある場合。The only exception to this is the schema namespace ("http://www.w3.org/2001/XMLSchema") – if the type’s data contract is in this namespace, the corresponding global element is in the blank namespace because it is forbidden to add new elements to the schema namespace. 型に XmlRootAttribute 属性が適用されている場合、グローバル要素宣言は、ElementNameNamespace、および IsNullable の各プロパティを使用してエクスポートされます。If the type has the XmlRootAttribute attribute applied to it, the global element declaration is exported using the following: ElementName, Namespace and IsNullable properties. XmlRootAttribute が適用された場合の既定値は、データ コントラクト名、空白の名前空間、および true に設定された "nillable" です。The defaults with XmlRootAttribute applied are the data contract name, a blank namespace and "nillable" being true.

同じグローバル要素宣言の規則が、従来のデータセット型に適用されます。The same global element declaration rules apply to legacy dataset types. XmlRootAttribute は、カスタム コードによって追加されたグローバル要素宣言をオーバーライドできません。これには、スキーマ プロバイダー メソッドを使用して XmlSchemaSet に追加された場合と、従来のデータセット型に対して GetSchema を使用して追加された場合があります。Note that the XmlRootAttribute cannot override global element declarations added through custom code, either added to the XmlSchemaSet using the schema provider method or through GetSchema for legacy dataset types.

IXmlSerializable 要素型IXmlSerializable Element Types

IXmlSerializable 要素型には、IsAny に設定された true プロパティか、null を返すスキーマ プロバイダー メソッドのいずれかが含まれています。IXmlSerializable element types have either the IsAny property set to true or have their schema provider method return null.

要素型のシリアル化と逆シリアル化は、コンテンツ型のシリアル化と逆シリアル化に非常に似ています。Serializing and deserializing an element type is very similar to serializing and deserializing a content type. ただし、重要な違いがいくつかあります。However, there are some important differences:

  • WriteXml の実装では、要素 (これには複数の子要素が含まれている可能性もありますが) を 1 つだけ出力することが想定されています。The WriteXml implementation is expected to write exactly one element (which could of course contain multiple child elements). この 1 つの要素の外側にある属性、複数の兄弟要素、またはこれらが混在したコンテンツを出力することはできません。It should not be writing attributes outside of this single element, multiple sibling elements or mixed content. 要素は空であってもかまいません。The element may be empty.

  • ReadXml の実装では、ラッパー要素の読み取りは想定されていません。The ReadXml implementation should not read the wrapper element. 読み取ることが想定されているのは、WriteXml で生成される要素 1 つのみです。It is expected to read the one element that WriteXml produces.

  • 要素型を一様にシリアル化する場合 (データ コントラクトのデータ メンバーとしてシリアル化する場合など) は、コンテンツ型の場合と同様に、WriteXml を呼び出す前にラッパー要素が出力されます。When serializing an element type regularly (for example, as a data member in a data contract), the serializer outputs a wrapper element before calling WriteXml, as with content types. ただし、WriteXml コンストラクターまたは DataContractSerializer コンストラクターによるシリアライザーの構築時にルート名と名前空間が明示的に指定されていない限り、トップ レベルで要素型をシリアル化しても、通常は NetDataContractSerializer で書き出される要素を囲むラッパー要素が出力されることはありません。However, when serializing an element type at the top level, the serializer does not normally output a wrapper element at all around the element that WriteXml writes, unless a root name and namespace were explicitly specified when constructing the serializer in the DataContractSerializer or NetDataContractSerializer constructors. 詳細については、次を参照してください。シリアル化および逆シリアル化します。For more information, see Serialization and Deserialization.

  • 構築時にルート名と名前空間を指定せずにトップ レベルで要素型をシリアル化した場合、WriteStartObjectWriteEndObject では基本的に何も実行されず、WriteObjectContent によって WriteXml が呼び出されます。When serializing an element type at the top level without specifying the root name and namespace at construction time, WriteStartObject and WriteEndObject essentially does nothing and WriteObjectContent calls WriteXml. このモードでは、シリアル化されるオブジェクトは null にできず、ポリモーフィックに割り当てることができません。In this mode, the object being serialized cannot be null and cannot be polymorphically assigned. また、オブジェクト グラフの保存を有効化できず、NetDataContractSerializer も使用できません。Also, object graph preservation cannot enabled and the NetDataContractSerializer cannot be used.

  • 構築時にルート名と名前空間を指定せずにトップ レベルで要素型を逆シリアル化したときに、要素の先頭を検出できた場合は、IsStartObjecttrue を返します。When deserializing an element type at the top level without specifying the root name and namespace at construction time, IsStartObject returns true if it can find the start of any element. ReadObject パラメーターが verifyObjectName に設定されている true は、実際にオブジェクトを読み取る前の動作が IsStartObject と同様です。ReadObject with the verifyObjectName parameter set to true behaves in the same way as IsStartObject before actually reading the object. その後、ReadObject は制御を ReadXml メソッドに渡します。ReadObject then passes control to ReadXml method.

要素型の場合も、エクスポートされるスキーマは、前のセクションで説明した XmlElement 型に対するスキーマと同じです。ただし、スキーマ プロバイダー メソッドは、コンテンツ型と同様、追加のスキーマを XmlSchemaSet に追加できます。The schema exported for element types is the same as for the XmlElement type as described in an earlier section, except that the schema provider method can add any additional schema to the XmlSchemaSet as with content types. 要素型には XmlRootAttribute 属性を使用することはできないので、グローバル要素宣言は要素型に対して出力されません。Using the XmlRootAttribute attribute with element types is not allowed, and global element declarations are never emitted for these types.

XmlSerializer との相違点Differences from the XmlSerializer

IXmlSerializable インターフェイス、XmlSchemaProviderAttribute 属性、および XmlRootAttribute 属性は、XmlSerializer でも認識されます。The IXmlSerializable interface and the XmlSchemaProviderAttribute and XmlRootAttribute attributes are also understood by the XmlSerializer . ただし、データ コントラクト モデルでの処理方法に違いがあります。However, there are some differences in how these are treated in the data contract model. 重要な違いを以下にまとめます。The important differences are summarized in the following:

  • スキーマ プロバイダー メソッドは、XmlSerializer で使用できるようにするためにパブリックにする必要がありますが、データ コントラクト モデルで使用するためにパブリックにする必要はありません。The schema provider method must be public to be usable in the XmlSerializer, but does not have to be public to be usable in the data contract model.

  • スキーマ プロバイダー メソッドは、データ コントラクト モデルで IsAny が true の場合に呼び出されますが、XmlSerializer では呼び出されません。The schema provider method is called when IsAny is true in the data contract model but not with the XmlSerializer.

  • コンテンツ型または従来のデータセット型に XmlRootAttribute 属性がない場合、XmlSerializer は、グローバル要素宣言を空白の名前空間にエクスポートします。When the XmlRootAttribute attribute is not present for content or legacy dataset types, the XmlSerializer exports a global element declaration in the blank namespace. データ コントラクト モデルで通常使用される名前空間は、前に説明したとおりデータ コントラクトの名前空間です。In the data contract model, the namespace used is normally the data contract namespace as described earlier.

両方のシリアル化技術で使用する型を作成する場合には、これらの違いに注意してください。Be aware of these differences when creating types that are used with both serialization technologies.

IXmlSerializable スキーマのインポートImporting IXmlSerializable Schema

IXmlSerializable 型から生成されたスキーマをインポートする場合、次のような状況が考えられます。When importing a schema generated from IXmlSerializable types, there are a few possibilities:

  • 」の説明に従って、生成されたスキーマは、有効なデータ コントラクト スキーマにありますData Contract Schema Referenceします。The generated schema may be a valid data contract schema as described in Data Contract Schema Reference. この場合は、スキーマを通常どおりにインポートでき、通常のデータ コントラクト型が生成されます。In this case, schema can be imported as usual and regular data contract types are generated.

  • 生成されたスキーマが、有効なデータ コントラクト スキーマではない場合があります。The generated schema may not be a valid data contract schema. たとえば、スキーマ プロバイダー メソッドによって、データ コントラクト モデルでサポートされていない XML 属性を含むスキーマが生成されることがあります。For example, your schema provider method may generate schema that involves XML attributes which are not supported in the data contract model. この場合、スキーマを IXmlSerializable 型としてインポートできます。In this case, you can import the schema as IXmlSerializable types. このインポート モードが既定で上にないが簡単で有効にできる – など、/importXmlTypesコマンド ライン スイッチをServiceModel メタデータ ユーティリティ ツール (Svcutil.exe)します。This import mode is not on by default but can easily be enabled – for example, with the /importXmlTypes command-line switch to the ServiceModel Metadata Utility Tool (Svcutil.exe). 詳細に記載されて、クラスを生成するスキーマをインポートします。This is described in detail in the Importing Schema to Generate Classes. 型インスタンスを処理するには、XML を直接操作する必要があります。Note that you must work directly with the XML for your type instances. XmlSerializer の使用方法に関するトピックを参照し、より広い範囲のスキーマをサポートする別のシリアル化技術を使用することを検討することもできます。You may also consider using a different serialization technology that supports a wider range of schema – see the topic on using the XmlSerializer.

  • 新しい型を生成する代わりに、プロキシ内の既存の IXmlSerializable 型を再利用できます。You may want to reuse your existing IXmlSerializable types in the proxy instead of generating new ones. この場合、「型を作成するためのスキーマのインポート」で説明する参照型の機能を使用して、再利用する型を示すことができます。In this case, the referenced types feature described in the Importing Schema to Generate Types topic can be used to indicate the type to reuse. これは、Svcutil.exe で /reference スイッチを使用して、再利用する型を含むアセンブリを指定することに相当します。This corresponds to using the /reference switch on svcutil.exe, which specifies the assembly that contains the types to reuse.

データ コントラクトでの任意の XML の表現Representing Arbitrary XML in Data Contracts

XmlElement 型、XmlNode の配列、および IXmlSerializable 型を使用すると、任意の XML をデータ コントラクト モデルに挿入できます。The XmlElement, Array of XmlNode and IXmlSerializable types allow you to inject arbitrary XML into the data contract model. DataContractSerializerNetDataContractSerializer は、プロセスには介入せずに、使用している XML ライターにこの XML コンテンツを渡します。The DataContractSerializer and NetDataContractSerializer pass this XML content on to the XML writer in use, without interfering in the process. ただし、XML ライターは、出力する XML に対して特定の制限を適用することがあります。However, the XML writers may enforce certain restrictions on the XML that they write. 次に重要な例を具体的に示します。Specifically, here are some important examples:

  • XML ライターは通常は XML ドキュメントの宣言を許可しない (たとえば、<ですか? xml バージョン ='1.0 ' ですか? >) 別のドキュメントの書き込み中。The XML writers do not typically allow an XML document declaration (for example, <?xml version=’1.0’ ?>) in the middle of writing another document. 完全な XML ドキュメントを取得して、それを Array データ メンバーの XmlNode としてシリアル化したりすることはできません。You cannot take a full XML document and serialize it as an Array of XmlNode data member. これを実行するには、ドキュメントの宣言を取り除くか、独自のエンコード方法でこの宣言を表現する必要があります。To do this, you have to either strip out the document declaration or use your own encoding scheme to represent it.

  • すべての WCF に付属している XML ライターでは、XML 処理命令 (<でしょうか。All of the XML writers supplied with WCF reject XML processing instructions (<? ? >) と文書型定義 (<!?>) and document type definitions (<! >)、SOAP メッセージではできないためです。>), because they are not allowed in SOAP messages. この場合も、独自のエンコード機構を使用して、この制限に対処できます。Again, you can use your own encoding mechanism to get around this restriction. 生成される XML に XML 処理命令と文書型定義を含める必要がある場合は、この 2 つをサポートする XML ライターを使用するカスタム エンコーダーを作成できます。If you must include these in your resultant XML, you can write a custom encoder that uses XML writers that support them.

  • WriteXml を実装するときは、XML ライターで WriteRaw メソッドを呼び出さないようにします。When implementing WriteXml, avoid calling WriteRaw method on the XML writer. WCF は、さまざまな XML のエンコーディング (バイナリを含む) を使用して、非常に困難かを使用してがWriteRaw結果がどのエンコードでも使用できるようにします。WCF uses a variety of XML encodings (including binary), it is very difficult or impossible to use WriteRaw such that the result is usable in any encoding.

  • 実装するときにWriteXmlを使用しないでください、WriteEntityRefWriteNmTokenWCF に付属している XML ライターでサポートされていないメソッドです。When implementing WriteXml, avoid using the WriteEntityRef and WriteNmToken methods that are unsupported on the XML writers supplied with WCF.

DataSet、Typed DataSet、および DataTable の使用Using DataSet, Typed DataSet and DataTable

データ コントラクト モデルでは、この 3 つの型の使用が完全にサポートされています。Using these types is fully supported in the data contract model. これらの型を使用する場合は、次の点に注意してください。When using these types, consider the following points:

  • これらの型のスキーマ (特にDataSetとその型指定された派生クラス) 一部の WCF 以外のプラットフォームと相互運用ができないか、これらのプラットフォームを使用するとユーザビリティの低い可能性があります。The schema for these types (especially DataSet and its typed derived classes) may not be interoperable with some non-WCF platforms, or may result in poor usability when used with these platforms. また、DataSet 型の使用はパフォーマンスに影響を与えることがあります。Additionally, using the DataSet type may have performance implications. さらに、将来的にアプリケーションのバージョン管理が通常より難しくなる可能性もあります。Finally, it may make it more difficult for you to version your application in the future. コントラクトでは、DataSet 型の代わりに、明示的に定義されたデータ コントラクト型を使用することを検討してください。Consider using explicitly defined data contract types instead of DataSet types in your contracts.

  • DataSet スキーマまたは DataTable スキーマをインポートする際には、これらの型を参照することが重要です。When importing DataSet or DataTable schema, it is important to reference these types. これは Svcutil.exe コマンド ライン ツールでは、System.Data.dll アセンブリ名を渡すことによって実現できます、/referenceスイッチします。With the Svcutil.exe command-line tool, this can be accomplished by passing the System.Data.dll assembly name to the /reference switch. 型指定されたデータセット スキーマをインポートする場合、その型指定されたデータセットの型を参照する必要があります。If importing typed dataset schema, you must reference the typed dataset’s type. Svcutil.exe を使用して渡すために、型指定されたデータセットのアセンブリの場所、/referenceスイッチします。With Svcutil.exe, pass the location of the typed dataset’s assembly to the /reference switch. 型の参照の詳細については、次を参照してください。、クラスを生成するスキーマをインポートします。For more information about referencing types, see the Importing Schema to Generate Classes.

データ コントラクト モデルでは、型指定された DataSet のサポートが制限されています。Support for typed DataSets in the data contract model is limited. 型指定された DataSet は、シリアル化と逆シリアル化が可能であり、スキーマをエクスポートすることもできます。Typed DataSets can be serialized and deserialized and can export their schema. ただし、データ コントラクト スキーマのインポートでは、既存のスキーマの再利用のみが行われるため、型指定された新しい DataSet 型をスキーマから生成することはできません。However, the Data Contract schema import is unable to generate new typed DataSet types from the schema, as it can only reuse existing ones. Svcutil.exe ツールで /r スイッチを使用して、型指定された既存の DataSet を指し示すことができます。You can point to an existing typed DataSet by using the /r switch on Svcutil.exe. 型指定されたデータセットを使用するサービスで、/r スイッチを指定せずに Svcutil.exe を使用しようとすると、代替のシリアライザー (XmlSerializer) が自動的に選択されます。If you attempt to use a Svcutil.exe without the /r switch on a service that uses a typed dataset, an alternative serializer (XmlSerializer) is automatically selected. DataContractSerializer を使用することも、スキーマから DataSet を生成することも必要である場合は、(サービスで /d スイッチを指定した Xsd.exe ツールを使用して) 型指定された DataSet 型を生成し、型をコンパイルした後に、Svcutil.exe で /r スイッチを使用して、それらの型を指し示します。If you must use the DataContractSerializer and must generate DataSets from schema, you can use the following procedure: generate the typed DataSet types (by using the Xsd.exe tool with the /d switch on the service), compile the types, and then point to them using the /r switch on Svcutil.exe.

関連項目See also