XmlSerializer クラスの使用Using the XmlSerializer Class

Windows Communication Foundation (WCF) は、2 つの別のシリアル化テクノロジを使用して、クライアントとサービス、シリアル化と呼ばれるプロセス間で送信される XML に、アプリケーションでデータを有効にできます。Windows Communication Foundation (WCF) can use two different serialization technologies to turn the data in your application into XML that is transmitted between clients and services, a process called serialization.

既定としての DataContractSerializerDataContractSerializer as the Default

既定で WCF を使用して、DataContractSerializerデータ型をシリアル化するクラス。By default WCF uses the DataContractSerializer class to serialize data types. このシリアライザーは、次の型をサポートします。This serializer supports the following types:

  • プリミティブ型 (整数、文字列、バイト配列など) や、プリミティブとして処理される XmlElementDateTime などの特殊な型。Primitive types (for example, integers, strings, and byte arrays), as well as some special types, such as XmlElement and DateTime, which are treated as primitives.

  • データ コントラクト型 (DataContractAttribute 属性でマークされた型)。Data contract types (types marked with the DataContractAttribute attribute).

  • SerializableAttribute インターフェイスを実装する型など、ISerializable 属性でマークされた型。Types marked with the SerializableAttribute attribute, which include types that implement the ISerializable interface.

  • IXmlSerializable インターフェイスを実装する型。Types that implement the IXmlSerializable interface.

  • 多くのジェネリック コレクション型を含む多くの共通コレクション型。Many common collection types, which include many generic collection types.

多くの .NET Framework 型は後者の 2 つのカテゴリに分類されシリアル化可能なしたがってします。Many .NET Framework types fall into the latter two categories and are thus serializable. シリアル化可能な型の配列もシリアル化可能です。Arrays of serializable types are also serializable. 完全な一覧についてを参照してください。 Data Transfer in Service Contracts にを指定するします。For a complete list, see Specifying Data Transfer in Service Contracts.

DataContractSerializerコントラクト型のデータと共に使用される、新しい WCF サービスを作成することをお勧めします。The DataContractSerializer, used together with data contract types, is the recommended way to write new WCF services. 詳細については、次を参照してください。 Using Data Contractsします。For more information, see Using Data Contracts.

XmlSerializer クラスを使用する場合When to Use the XmlSerializer Class

WCF がサポートすることも、XmlSerializerクラス。WCF also supports the XmlSerializer class. XmlSerializerクラスは WCF に固有ではありません。The XmlSerializer class is not unique to WCF. これは、ASP.NET Web サービスを使用する同じシリアル化エンジンです。It is the same serialization engine that ASP.NET Web services use. XmlSerializer クラスでは、DataContractSerializer クラスよりもサポートされる型の範囲がずっと狭くなりますが、結果の XML に対する制御の柔軟性に優れています。また、XML スキーマ定義言語 (XSD) 標準のサポート範囲が広く、The XmlSerializer class supports a much narrower set of types than the DataContractSerializer class, but allows much more control over the resulting XML and supports much more of the XML Schema definition language (XSD) standard. シリアル化可能な型で宣言型属性が要求されません。It also does not require any declarative attributes on the serializable types. 詳細については、.NET Framework ドキュメントの XML シリアル化のトピックを参照してください。For more information, see the XML Serialization topic in the .NET Framework documentation. XmlSerializer クラスは、データ コントラクト型をサポートしません。The XmlSerializer class does not support data contract types.

Svcutil.exe を使用する場合、またはサービス参照の追加Visual Studio でのサード パーティのサービスでは、クライアント コードを生成またはサード パーティ製のスキーマでは、適切なシリアライザーにアクセスする機能が自動的に選択します。When using Svcutil.exe or the Add Service Reference feature in Visual Studio to generate client code for a third-party service, or to access a third-party schema, an appropriate serializer is automatically selected for you. スキーマに DataContractSerializer との互換性がない場合は、XmlSerializer が選択されます。If the schema is not compatible with the DataContractSerializer, the XmlSerializer is selected.

XmlSerializer への手動切り替えManually Switching to the XmlSerializer

XmlSerializer に手動で切り替える必要が生じる場合もあります。At times, you may have to manually switch to the XmlSerializer. たとえば、次のような場合です。This happens, for example, in the following cases:

  • アプリケーションを ASP.NET Web サービスから WCF に移行する場合は、既存の再利用たいXmlSerializer-新しいデータを作成する代わりに、互換性のある型のコントラクト型。When migrating an application from ASP.NET Web services to WCF, you may want to reuse existing, XmlSerializer-compatible types instead of creating new data contract types.

  • メッセージに表示する XML に対する正確な制御が必要で、Web サービス記述言語 (WSDL) ドキュメントが利用できない場合。たとえば、DataContractSerializer と互換性がなく、標準化および公開されている特定のスキーマに従う必要のある型を使用して、サービスを作成する場合。When precise control over the XML that appears in messages is important, but a Web Services Description Language (WSDL) document is not available, for example, when creating a service with types that have to comply to a certain standardized, published schema that is not compatible with the DataContractSerializer.

  • 従来の SOAP エンコード標準に従うサービスを作成する場合。When creating services that follow the legacy SOAP Encoding standard.

上記を含めた多様な状況で、次のコードに示すように、XmlSerializer 属性をサービスに適用することにより、XmlSerializerFormatAttribute クラスに手動で切り替えることができます。In these and other cases, you can manually switch to the XmlSerializer class by applying the XmlSerializerFormatAttribute attribute to your service, as shown in the following code.

[ServiceContract]
[XmlSerializerFormat]
public class BankingService
{
[OperationContract]
    public void ProcessTransaction(BankingTransaction bt)
    {
        // Code not shown.
    }
    
}

//BankingTransaction is not a data contract class,
//but is an XmlSerializer-compatible class instead.
public class BankingTransaction
{
    [XmlAttribute]
    public string Operation;
    [XmlElement]
    public Account fromAccount;
    [XmlElement]
    public Account toAccount;
    [XmlElement]
    public int amount;
}
//Notice that the Account class must also be XmlSerializer-compatible.
<ServiceContract(), XmlSerializerFormat()>  _
Public Class BankingService
    <OperationContract()> _
    Public Sub ProcessTransaction(ByVal bt As BankingTransaction) 
       ' Code not shown.
    End Sub 
End Class 


' BankingTransaction is not a data contract class,
' but is an XmlSerializer-compatible class instead.

Public Class BankingTransaction
    <XmlAttribute()>  _
    Public Operation As String
    <XmlElement()>  _
    Public fromAccount As Account
    <XmlElement()>  _
    Public toAccount As Account
    <XmlElement()>  _
    Public amount As Integer
End Class
'Notice that the Account class must also be XmlSerializer-compatible.

セキュリティの考慮事項Security Considerations

注意

シリアル化エンジンを切り替える場合は注意が必要です。It is important to be careful when switching serialization engines. 同じ型でも、使用するシリアライザーによって XML へのシリアル化方法が異なる場合があります。The same type can serialize to XML differently depending on the serializer being used. 誤って、不適切なシリアライザーを使用すると、公開する意図のない型の情報が公開されるおそれがあります。If you accidentally use the wrong serializer, you might be disclosing information from the type that you did not intend to disclose.

たとえば、DataContractSerializer クラスは、データ コントラクト型をシリアル化する場合、DataMemberAttribute 属性でマークされたメンバーのみをシリアル化します。For example, the DataContractSerializer class only serializes members marked with the DataMemberAttribute attribute when serializing data contract types. XmlSerializer クラスは、すべてのパブリック メンバーをシリアル化します。The XmlSerializer class serializes any public member. たとえば、次のコードの型を見てください。See the type in the following code.

[DataContract]
public class Customer
{
    [DataMember]
    public string firstName;
    [DataMember]
    public string lastName;
    public string creditCardNumber;
}
<DataContract()>  _
Public Class Customer
    <DataMember()>  _
    Public firstName As String
    <DataMember()>  _
    Public lastName As String
    Public creditCardNumber As String
End Class 

XmlSerializer クラスが選択されているサービス コントラクトでこの型が誤って使用された場合、意図したものではなくても creditCardNumber メンバーがシリアル化されます。If the type is inadvertently used in a service contract where the XmlSerializer class is selected, the creditCardNumber member is serialized, which is probably not intended.

DataContractSerializer クラスが既定の場合でも、DataContractFormatAttribute 属性をサービス コントラクト型に適用することで、このクラスをサービスに対して明示的に選択できます (ただし、この操作が必要になることはありません)。Even though the DataContractSerializer class is the default, you can explicitly select it for your service (although doing this should never be required) by applying the DataContractFormatAttribute attribute to the service contract type.

サービスで使用するシリアライザーはコントラクトにとって不可欠な部分です。別のバインディングを選択しても他の構成設定に変更しても、このシリアライザーを変更することはできません。The serializer used for the service is an integral part of the contract and cannot be changed by selecting a different binding or by changing other configuration settings.

XmlSerializer クラスについては、セキュリティに関する重要な考慮事項が他にもあります。Other important security considerations apply to the XmlSerializer class. 最初に、使用する WCF アプリケーションを強くお勧めします。、XmlSerializerクラスは、漏えいから保護するキーで署名されます。First, it is strongly recommended that any WCF application that uses the XmlSerializer class is signed with a key that is safeguarded from disclosure. このことは、XmlSerializer に手動で切り替える場合と、自動切り替えが行われる場合 (Svcutil.exe やサービス参照の追加などのツールによる) の両方でお勧めします。This recommendation applies both when a manual switch to the XmlSerializer is performed and when an automatic switch is performed (by Svcutil.exe, Add Service Reference, or a similar tool). ため、これは、XmlSerializerシリアル化エンジンの読み込みをサポートしているシリアル化アセンブリを事前生成アプリケーションと同じキーで署名されている限り、します。This is because the XmlSerializer serialization engine supports the loading of pre-generated serialization assemblies as long as they are signed with the same key as the application. 署名されていないアプリケーションは、アプリケーション フォルダーやグローバル アセンブリ キャッシュに配置される事前生成済みのシリアル化アセンブリで予想される名前に、悪意のあるアセンブリが一致するという危険性に対して完全に無防備になります。An unsigned application is completely unprotected from the possibility of a malicious assembly matching the expected name of the pre-generated serialization assembly being placed in the application folder or the global assembly cache. もちろん、攻撃者がこのようなアクションを行うには、この 2 つの場所のいずれかに対する書き込みアクセスをまず取得する必要があります。Of course, an attacker must first gain write access to one of these two locations to attempt this action.

XmlSerializer を使用するときに必ず存在するもう 1 つの脅威は、システムの一時フォルダーへの書き込みアクセスに関連するものです。Another threat that exists whenever you use XmlSerializer is related to write access to the system temporary folder. XmlSerializerシリアル化エンジンを作成し、一時的な使用シリアル化アセンブリこのフォルダーにします。The XmlSerializer serialization engine creates and uses temporary serialization assemblies in this folder. 一時フォルダーへの書き込みアクセスのあるプロセスであれば、悪意のあるコードによってこれらのシリアル化アセンブリが上書きされるおそれがあることに注意してください。You should be aware that any process with write access to the temporary folder may overwrite these serialization assemblies with malicious code.

XmlSerializer サポートのルールRules for XmlSerializer support

XmlSerializer 互換の属性は、コントラクト操作のパラメーターまたは戻り値に直接適用できません。You cannot directly apply XmlSerializer-compatible attributes to contract operation parameters or return values. ただし、次のコードに示すように、型指定されたメッセージ (メッセージ コントラクトの本文) には適用できます。However, they can be applied to typed messages (message contract body parts), as shown in the following code.

[ServiceContract]
[XmlSerializerFormat]
public class BankingService
{
    [OperationContract]
    public void ProcessTransaction(BankingTransaction bt)
    {
        //Code not shown.
    }
}

[MessageContract]
public class BankingTransaction
{
    [MessageHeader]
    public string Operation;
    [XmlElement, MessageBodyMember]
    public Account fromAccount;
    [XmlElement, MessageBodyMember]
    public Account toAccount;
    [XmlAttribute, MessageBodyMember]
    public int amount;
}
<ServiceContract(), XmlSerializerFormat()>  _
Public Class BankingService
    <OperationContract()> _
    Public Sub ProcessTransaction(ByVal bt As BankingTransaction) 
       'Code not shown.
    End Sub 
End Class 

<MessageContract()>  _
Public Class BankingTransaction
    <MessageHeader()>  _
    Public Operation As String
    <XmlElement(), MessageBodyMember()>  _
    Public fromAccount As Account
    <XmlElement(), MessageBodyMember()>  _
    Public toAccount As Account
    <XmlAttribute(), MessageBodyMember()>  _
    Public amount As Integer
End Class 

型指定されたメッセージのメンバーに適用する場合、型指定されたメッセージ属性で競合するプロパティは、この属性によりオーバーライドされます。When applied to typed message members, these attributes override properties that conflict on the typed message attributes. たとえば、次のコードの ElementName は、Name をオーバーライドします。For example, in the following code, ElementName overrides Name.

    [MessageContract]
    public class BankingTransaction
    {
        [MessageHeader] public string Operation;

        //This element will be <fromAcct> and not <from>:
        [XmlElement(ElementName="fromAcct"), MessageBodyMember(Name="from")] 
        public Account fromAccount;
        
        [XmlElement, MessageBodyMember] 
        public Account toAccount;
        
        [XmlAttribute, MessageBodyMember] 
        public int amount;
}
<MessageContract()>  _
Public Class BankingTransaction
    <MessageHeader()>  _
    Public Operation As String
    
    'This element will be <fromAcct> and not <from>:
    <XmlElement(ElementName := "fromAcct"), _
        MessageBodyMember(Name := "from")>  _
    Public fromAccount As Account
    
    <XmlElement(), MessageBodyMember()>  _
    Public toAccount As Account
    
    <XmlAttribute(), MessageBodyMember()>  _
    Public amount As Integer
End Class 

MessageHeaderArrayAttribute の使用時は、XmlSerializer 属性はサポートされません。The MessageHeaderArrayAttribute attribute is not supported when using the XmlSerializer.

注意

ここで、 XmlSerializer WCF 前にリリースは、次の例外をスローします。"スキーマの最上位レベルで宣言された要素を含めることはできませんmaxOccurs> 1。In this case, the XmlSerializer throws the following exception, which is released prior to WCF: "An element declared at the top level of a schema cannot have maxOccurs > 1. XmlArray ではなく、XmlArrayItem または XmlElementAttribute を使うか、Wrapped パラメーター スタイルを使って 'more' のラッパー要素を指定してください。" という例外がスローされます。Provide a wrapper element for 'more' by using XmlArray or XmlArrayItem instead of XmlElementAttribute, or by using the Wrapped parameter style."

この例外が出力された場合は、この状況が当てはまるかどうかを調査します。If you receive such an exception, investigate whether this situation applies.

WCF がサポートしていません、SoapIncludeAttributeXmlIncludeAttributeコントラクトのメッセージ コントラクトと操作の属性を使用して、KnownTypeAttribute属性の代わりにします。WCF does not support the SoapIncludeAttribute and XmlIncludeAttribute attributes in message contracts and operation contracts; use the KnownTypeAttribute attribute instead.

IXmlSerializable インターフェイスを実装する型Types that Implement 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.

警告

ポリモーフィック型をシリアル化する場合、XmlSchemaProviderAttribute を型に適用して、正しい型がシリアル化されるようにする必要があります。If you are serializing polymorphic types you must apply the XmlSchemaProviderAttribute to the type to ensure the correct type is serialized.

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. スキーマ プロバイダー メソッドの使用は、要素型ではオプションです。null でメソッド名の代わりに XmlSchemaProviderAttribute を指定できます。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 passes control to the WriteXml method. WriteXml 実装により、ラッパー要素に属性が追加されるなど、任意の XML が書き込まれることがあります。The WriteXml implementation can write any XML, which includes 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 passes 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 and 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 whether 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 are 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 do 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 list:

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

  • スキーマ プロバイダー メソッドは、データ コントラクト モデルで IsAnytrue の場合に呼び出されますが、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 that 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.

XmlSerializer の従来の動作XmlSerializer Legacy Behavior

.NET Framework 4.0 以前では、XmlSerializer が C# コードをファイルに書き込むことによって、一時的なシリアル化アセンブリが生成されます。In the .NET Framework 4.0 and earlier, the XmlSerializer generated temporary serialization assemblies by writing C# code to a file. さらに、このファイルがアセンブリとしてコンパイルされます。The file was then compiled into an assembly. この動作では、シリアライザーの起動時間が長くなるなど、望ましくない結果が生じることがあります。This behavior had some undesirable consequences like slowing the startup time for the serializer. .NET Framework 4.5 では、この動作が変更され、コンパイラを使用せずに、アセンブリが生成されるようになりました。In .NET Framework 4.5, this behavior was changed to generate the assemblies without requiring use of the compiler. 開発者によっては、生成された C# コードを確認したい場合もあります。Some developers may wish to see the generated C# code. 次の構成によって、この従来の動作を使用するように指定できます。You can specify to use this legacy behavior by the following configuration:

<?xml version="1.0" encoding="utf-8" ?>  
<configuration>  
  <system.xml.serialization>  
    <xmlSerializer tempFilesLocation='e:\temp\XmlSerializerBug' useLegacySerializerGeneration="true" />  
  </system.xml.serialization>  
  <system.diagnostics>  
    <switches>  
      <add name="XmlSerialization.Compilation" value="1" />  
    </switches>  
  </system.diagnostics>  
</configuration>  

など、互換性の問題に遭遇した場合、XmlSerializer非パブリックの新しいオーバーライドと派生クラスをシリアル化に失敗すると、次のように切り替えることができます、XMLSerializer次の構成を使用して従来の動作。If you run into compatibility issues, such as the XmlSerializer failing to serialize a derived class with a non-public new override, you can switch back to the XMLSerializer legacy behavior by using the following configuration:

<configuration>  
<appSettings>   
<add key="System:Xml:Serialization:UseLegacySerializerGeneration" value="true" />  
               </appSettings>  
</configuration>  

上記の構成を代わりに、.NET Framework 4.5 またはそれ以降のバージョンを実行するマシンで、次の構成を使用できます。As an alternative to the above configuration, you can use the following configuration on a machine running .NET Framework 4.5 or later version:

<configuration>  
<system.xml.serialization>  
<xmlSerializer useLegacySerializerGeneration="true"/>  
</system.xml.serialization>  
</configuration>  

注意

<xmlSerializer useLegacySerializerGeneration="true"/>スイッチは、.NET Framework 4.5 またはそれ以降のバージョンを実行するマシンでのみ機能します。The <xmlSerializer useLegacySerializerGeneration="true"/> switch only works on a machine running .NET Framework 4.5 or later version. 上記appSettingsアプローチは、すべての .NET Framework バージョンで動作します。The above appSettings approach works on all .NET Framework versions.

関連項目See also