多くの場合、サービス コントラクトは既存のサービスから作成する必要があります。 .NET Framework 4.5 以降では、コントラクト優先ツールを使用して、既存のサービスからデータ コントラクト クラスを自動的に作成できます。 コントラクト優先ツールを使用するには、XML スキーマ定義ファイル (XSD) をローカルにダウンロードする必要があります。ツールは HTTP 経由でリモート データ コントラクトをインポートできません。
コントラクト優先ツールは、ビルド タスクとして Visual Studio 2012 に統合されます。 ビルド タスクによって生成されるコード ファイルは、プロジェクトがビルドされるたびに作成されるため、プロジェクトは基になるサービス コントラクトの変更を簡単に採用できます。
コントラクト優先ツールでインポートできるスキーマの種類は次のとおりです。
<xsd:complexType>
<xsd:simpleType>
</xsd:simpleType>
</xsd:complexType>
単純型は、 Int16
や String
などのプリミティブである場合は生成されません。複合型が Collection
型の場合は生成されません。 型は、別の xsd:complexType
の一部である場合にも生成されません。 いずれの場合も、型はプロジェクト内の既存の型に対して参照されます。
プロジェクトへのデータ コントラクトの追加
コントラクト優先ツールを使用する前に、サービス コントラクト (XSD) をプロジェクトに追加する必要があります。 この概要では、次のコントラクトを使用してコントラクト優先関数を示します。 このサービス定義は、Bingの検索 API で使用されるサービス コントラクトの小さなサブセットです。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ServiceSchema"
targetNamespace="http://tempuri.org/ServiceSchema.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/ServiceSchema.xsd"
xmlns:mstns="http://tempuri.org/ServiceSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="SearchRequest">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Version" type="xs:string" default="2.2" />
<xs:element minOccurs="0" maxOccurs="1" name="Market" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="UILanguage" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="Query" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="AppId" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="Latitude" type="xs:double" />
<xs:element minOccurs="0" maxOccurs="1" name="Longitude" type="xs:double" />
<xs:element minOccurs="0" maxOccurs="1" name="Radius" type="xs:double" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="WebSearchOption">
<xs:restriction base="xs:string">
<xs:enumeration value="DisableHostCollapsing" />
<xs:enumeration value="DisableQueryAlterations" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
上記のサービス コントラクトをプロジェクトに追加するには、プロジェクトを右クリックし、[ 新規追加...] を選択します。 [テンプレート] ダイアログの [WCF] ウィンドウから [スキーマ定義] を選択し、新しいファイルに SampleContract.xsd という名前を付けます。 上記のコードをコピーして、新しいファイルのコード ビューに貼り付けます。
コントラクト優先オプションの構成
コントラクト優先オプションは、WCF プロジェクトの [プロパティ] メニューで構成できます。 コントラクト優先開発を有効にするには、プロジェクトのプロパティ ウィンドウの WCF ページで [ XSD を型定義言語として有効にする ] チェック ボックスをオンにします。
詳細プロパティを構成するには、[詳細設定] ボタンをクリックします。
コントラクトからコードを生成するために、次の詳細設定を構成できます。 設定は、プロジェクト内のすべてのファイルに対してのみ構成できます。現時点では、個々のファイルに対して設定を構成することはできません。
シリアライザー モード: この設定は、サービス コントラクト ファイルの読み取りに使用されるシリアライザーを決定します。 XML シリアライザーを選択すると、[コレクション型] オプションと [型の再利用] オプションが無効になります。 これらのオプションは 、データ コントラクト シリアライザーにのみ適用されます。
型の再利用: この設定では、型の再利用に使用するライブラリを指定します。 この設定は、 シリアライザー モード が データ コントラクト シリアライザーに設定されている場合にのみ適用されます。
コレクションの種類: この設定では、コレクション データ型に使用する完全修飾型またはアセンブリ修飾型を指定します。 この設定は、 シリアライザー モード が データ コントラクト シリアライザーに設定されている場合にのみ適用されます。
ディクショナリの種類: この設定では、ディクショナリ データ型に使用する完全修飾型またはアセンブリ修飾型を指定します。
EnableDataBinding: この設定では、データ バインディングを実装するために、すべてのデータ型に INotifyPropertyChanged インターフェイスを実装するかどうかを指定します。
ExcludedTypes:この設定では、参照されるアセンブリから除外する完全修飾型またはアセンブリ修飾型の一覧を指定します。 この設定は、 シリアライザー モード が データ コントラクト シリアライザーに設定されている場合にのみ適用されます。
GenerateInternalTypes: この設定では、内部としてマークされたクラスを生成するかどうかを指定します。 この設定は、 シリアライザー モード が データ コントラクト シリアライザーに設定されている場合にのみ適用されます。
GenerateSerializableTypes: この設定では、 SerializableAttribute 属性を持つクラスを生成するかどうかを指定します。 この設定は、 シリアライザー モード が データ コントラクト シリアライザーに設定されている場合にのみ適用されます。
ImportXMLTypes: この設定では、DataContractAttribute属性を持たないクラスにSerializableAttribute属性を適用するようにデータ コントラクト シリアライザーを構成するかどうかを指定します。 この設定は、 シリアライザー モード が データ コントラクト シリアライザーに設定されている場合にのみ適用されます。
SupportFx35TypedDataSets: この設定では、.NET Framework 3.5 用に作成された型指定されたデータ セットに追加機能を提供するかどうかを指定します。 シリアライザー モードが XML シリアライザーに設定されている場合、この値が True に設定されている場合、TypedDataSetSchemaImporterExtensionFx35拡張機能が XML スキーマ インポーターに追加されます。 シリアライザー モードがデータ コントラクト シリアライザーに設定されている場合、この値が False に設定されている場合、DateTimeOffset型は参照から除外されるため、古いバージョンのフレームワークに対して常にDateTimeOffsetが生成されます。
InputXsdFiles: この設定では、入力ファイルの一覧を指定します。 各ファイルには、有効な XML スキーマが含まれている必要があります。
言語: この設定は、生成されたコントラクト コードの言語を指定します。 この設定は、 CodeDomProviderで認識できる必要があります。
NamespaceMappings: この設定では、XSD ターゲット名前空間から CLR 名前空間へのマッピングを指定します。 各マッピングでは、次の形式を使用する必要があります。
"Schema Namespace, CLR Namespace"
XML シリアライザーは、次の形式の 1 つのマッピングのみを受け入れます。
"*, CLR Namespace"
OutputDirectory: この設定では、コード ファイルが生成されるディレクトリを指定します。
この設定は、プロジェクトのビルド時にサービス コントラクト ファイルからサービス コントラクトの種類を生成するために使用されます。
コントラクト優先開発の使用
プロジェクトにサービス コントラクトを追加し、ビルド設定を確認したら、 F6 キーを押してプロジェクトをビルドします。 サービス コントラクトで定義されている型は、プロジェクトで使用できるようになります。
サービス コントラクトで定義されている型を使用するには、現在の名前空間の下に ContractTypes
への参照を追加します。
using MyProjectNamespace.ContractTypes;
サービス コントラクトで定義されている型は、次に示すように、プロジェクトで解決できます。
ツールによって生成された型は、GeneratedXSDTypes.cs ファイルに作成されます。 このファイルは、既定で <project ディレクトリ>/obj/<build 構成>/XSDGeneratedCode/ ディレクトリに作成されます。 この記事の冒頭にあるサンプル スキーマは、次のように変換されます。
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17330
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace TestXSD3.ContractTypes
{
using System.Xml.Serialization;
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.17330")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd", IsNullable=true)]
public partial class SearchRequest
{
private string versionField;
private string marketField;
private string uILanguageField;
private string queryField;
private string appIdField;
private double latitudeField;
private bool latitudeFieldSpecified;
private double longitudeField;
private bool longitudeFieldSpecified;
private double radiusField;
private bool radiusFieldSpecified;
public SearchRequest()
{
this.versionField = "2.2";
}
/// <remarks/>
[System.ComponentModel.DefaultValueAttribute("2.2")]
public string Version
{
get
{
return this.versionField;
}
set
{
this.versionField = value;
}
}
/// <remarks/>
public string Market
{
get
{
return this.marketField;
}
set
{
this.marketField = value;
}
}
/// <remarks/>
public string UILanguage
{
get
{
return this.uILanguageField;
}
set
{
this.uILanguageField = value;
}
}
/// <remarks/>
public string Query
{
get
{
return this.queryField;
}
set
{
this.queryField = value;
}
}
/// <remarks/>
public string AppId
{
get
{
return this.appIdField;
}
set
{
this.appIdField = value;
}
}
/// <remarks/>
public double Latitude
{
get
{
return this.latitudeField;
}
set
{
this.latitudeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool LatitudeSpecified
{
get
{
return this.latitudeFieldSpecified;
}
set
{
this.latitudeFieldSpecified = value;
}
}
/// <remarks/>
public double Longitude
{
get
{
return this.longitudeField;
}
set
{
this.longitudeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool LongitudeSpecified
{
get
{
return this.longitudeFieldSpecified;
}
set
{
this.longitudeFieldSpecified = value;
}
}
/// <remarks/>
public double Radius
{
get
{
return this.radiusField;
}
set
{
this.radiusField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool RadiusSpecified
{
get
{
return this.radiusFieldSpecified;
}
set
{
this.radiusFieldSpecified = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.17330")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd", IsNullable=false)]
public enum WebSearchOption
{
/// <remarks/>
DisableHostCollapsing,
/// <remarks/>
DisableQueryAlterations,
}
}
エラーと警告
XSD スキーマの解析で発生したエラーと警告は、ビルド エラーと警告として表示されます。
インターフェイスの継承
コントラクト優先開発でインターフェイス継承を使用することはできません。これは、他の操作でのインターフェイスの動作と一致します。 基本インターフェイスを継承するインターフェイスを使用するには、2 つの個別のエンドポイントを使用します。 最初のエンドポイントは継承されたコントラクトを使用し、2 番目のエンドポイントは基本インターフェイスを実装します。