システムによって提供されないバインディングを作成するには、いくつかの方法があります。
バインド要素を格納するコンテナーである CustomBinding クラスに基づいて、カスタム バインドを作成します。 その後、カスタム バインドがサービス エンドポイントに追加されます。 カスタム バインドは、プログラムまたはアプリケーション構成ファイルで作成できます。 アプリケーション構成ファイルのバインド要素を使用するには、バインド要素を BindingElementExtensionElement拡張する必要があります。 カスタム バインドの詳細については、「 カスタム バインド と CustomBinding」を参照してください。
標準バインディングから派生するクラスを作成できます。 たとえば、 WSHttpBinding からクラスを派生させ、 CreateBindingElements メソッドをオーバーライドしてバインド要素を取得し、カスタム バインド要素を挿入したり、セキュリティのために特定の値を設定したりすることができます。
新しい Binding 型を作成して、バインディング実装全体を完全に制御できます。
バインド要素の順序
各バインド要素は、メッセージの送受信時の処理ステップを表します。 実行時に、バインディング要素によって、送信チャネル スタックと受信チャネル スタックを構築するために必要なチャネルとリスナーが作成されます。
バインディング要素には、プロトコル バインド要素、エンコード バインド要素、トランスポート バインド要素の 3 種類があります。
プロトコル バインディング要素 – これらの要素は、メッセージに対して動作する上位レベルの処理手順を表します。 これらのバインド要素によって作成されたチャネルとリスナーは、メッセージの内容を追加、削除、または変更できます。 特定のバインディングには任意の数のプロトコル バインド要素があり、それぞれが BindingElementから継承されます。 Windows Communication Foundation (WCF) には、 ReliableSessionBindingElement や SymmetricSecurityBindingElementなど、いくつかのプロトコル バインド要素が含まれています。
Encoding Binding 要素 – これらの要素は、メッセージと、ネットワーク上で伝送できるエンコードの間の変換を表します。 一般的な WCF バインドには、1 つのエンコード バインド要素が含まれます。 エンコード バインド要素の例としては、 MtomMessageEncodingBindingElement、 BinaryMessageEncodingBindingElement、 TextMessageEncodingBindingElementなどがあります。 バインディングにエンコード バインド要素が指定されていない場合は、既定のエンコードが使用されます。 トランスポートが HTTP の場合は既定値はテキストで、それ以外の場合はバイナリです。
トランスポート バインド要素 – これらの要素は、トランスポート プロトコルでのエンコード メッセージの送信を表します。 一般的な WCF バインディングには、 TransportBindingElementから継承されるトランスポート バインド要素が 1 つだけ含まれます。 トランスポート バインド要素の例としては、 TcpTransportBindingElement、 HttpTransportBindingElement、および NamedPipeTransportBindingElementがあります。
新しいバインドを作成する場合は、追加されたバインド要素の順序が重要です。 バインド要素は、常に次の順序で追加します。
レイヤー | オプション | 必須 |
---|---|---|
トランザクション フロー | System.ServiceModel.Channels.TransactionFlowBindingElement | いいえ |
信頼性 | System.ServiceModel.Channels.ReliableSessionBindingElement | いいえ |
安全 | System.ServiceModel.Channels.SecurityBindingElement | いいえ |
複合二重 | System.ServiceModel.Channels.CompositeDuplexBindingElement | いいえ |
[エンコード] | Text、Binary、MTOM、Custom | はい* |
トランスポート | TCP、名前付きパイプ、HTTP、HTTPS、MSMQ、カスタム | イエス |
*各バインディングにはエンコードが必要であるため、エンコードが指定されていない場合は、WCF によって既定のエンコードが追加されます。 既定値は HTTP トランスポートと HTTPS トランスポートの Text/XML、それ以外の場合はバイナリです。
新しい Binding 要素の作成
WCF によって提供される BindingElement から派生した型に加えて、独自のバインド要素を作成できます。 これにより、スタック内の他のシステム提供型で構成できる独自の BindingElement を作成することで、バインドのスタックの作成方法とその中に入るコンポーネントをカスタマイズできます。
たとえば、データベースにメッセージをログ記録する機能を提供する LoggingBindingElement
を実装する場合は、チャネル スタック内のトランスポート チャネルの上に配置する必要があります。 この場合、アプリケーションは、次の例のように、TcpTransportBindingElement
を使用してLoggingBindingElement
を構成するカスタム バインドを作成します。
Binding customBinding = new CustomBinding(
new LoggingBindingElement(),
new TcpTransportBindingElement()
);
新しいバインド要素を記述する方法は、その正確な機能によって異なります。 サンプルの 1 つである Transport: UDP では、1 種類のバインド要素を実装する方法の詳細な説明が提供されています。
新しいバインドの作成
ユーザーが作成したバインド要素は、2 つの方法で使用できます。 前のセクションでは、カスタム バインドを使用する最初の方法を示します。 カスタム バインドを使用すると、ユーザーが作成したバインディング要素を含む任意のバインド要素セットに基づいて、独自のバインドを作成できます。
複数のアプリケーションでバインドを使用する場合は、独自のバインドを作成し、 Bindingを拡張します。 これにより、カスタム バインドを使用するたびに手動で作成することが回避されます。 ユーザー定義バインドを使用すると、バインドの動作を定義し、ユーザー定義のバインド要素を含めることができます。 また、 事前にパッケージ化されています。バインドを使用するたびに再構築する必要はありません。
少なくとも、ユーザー定義バインディングは、 CreateBindingElements メソッドと Scheme プロパティを実装する必要があります。
CreateBindingElements メソッドは、バインディングのバインド要素を含む新しいBindingElementCollectionを返します。 コレクションは順序付けされ、最初にプロトコル バインド要素、次にエンコード バインド要素、トランスポート バインド要素が含まれている必要があります。 WCF システム提供のバインド要素を使用する場合は、 カスタム バインドで指定されたバインド要素の順序付け規則に従う必要があります。 このコレクションは、ユーザー定義バインディング クラス内で参照されるオブジェクトを参照しないでください。したがって、バインド作成者は、CreateBindingElementsの呼び出しごとにBindingElementCollectionのClone()
を返す必要があります。
Scheme プロパティは、バインディングで使用されているトランスポート プロトコルの URI スキームを表します。 たとえば、 WSHttpBinding と NetTcpBinding は、それぞれの Scheme プロパティから "http" と "net.tcp" を返します。
ユーザー定義バインディングの省略可能なメソッドとプロパティの完全な一覧については、 Bindingを参照してください。
例
この例では、Bindingから派生したSampleProfileUdpBinding
にプロファイル バインドを実装します。
SampleProfileUdpBinding
には、ユーザーが作成した 1 つのUdpTransportBindingElement
と、TextMessageEncodingBindingElement
、CompositeDuplexBindingElement
、ReliableSessionBindingElement
の 3 つのシステム提供の最大 4 つのバインド要素が含まれています。
public override BindingElementCollection CreateBindingElements()
{
BindingElementCollection bindingElements = new BindingElementCollection();
if (ReliableSessionEnabled)
{
bindingElements.Add(session);
bindingElements.Add(compositeDuplex);
}
bindingElements.Add(encoding);
bindingElements.Add(transport);
return bindingElements.Clone();
}
二重コントラクトを使用したセキュリティ制限
すべてのバインド要素が互いに互換性があるわけではありません。 特に、双方向コントラクトで使用する場合、セキュリティ バインディング要素にはいくつかの制限があります。
One-Shot セキュリティ
<message>構成要素のnegotiateServiceCredential
属性をfalse
に設定することで、必要なすべてのセキュリティ資格情報が 1 つのメッセージで送信される "ワンショット" セキュリティを実装できます。
ワンショット認証は、双方向コントラクトでは機能しません。
Request-Reply コントラクトの場合、ワンショット認証は、セキュリティ バインディング要素の下のバインディング スタックが IRequestChannel インスタンスまたは IRequestSessionChannel インスタンスの作成をサポートしている場合にのみ機能します。
一方向コントラクトの場合、セキュリティ バインド要素の下のバインド スタックで IRequestChannel、 IRequestSessionChannel、 IOutputChannel 、または IOutputSessionChannel インスタンスの作成がサポートされている場合、ワンショット認証が機能します。
Cookie モードのセキュリティ コンテキスト トークン
Cookie モードのセキュリティ コンテキスト トークンは、双方向コントラクトでは使用できません。
Request-Reply コントラクトの場合、Cookie モードのセキュリティ コンテキスト トークンは、セキュリティ バインド要素の下のバインディング スタックが IRequestChannel または IRequestSessionChannel インスタンスの作成をサポートしている場合にのみ機能します。
一方向コントラクトの場合、Cookie モードのセキュリティ コンテキスト トークンは、セキュリティ バインド要素の下のバインド スタックが IRequestChannel インスタンスまたは IRequestSessionChannel インスタンスの作成をサポートしている場合に機能します。
セッション モードのセキュリティ コンテキスト トークン
セッション モード SCT は、セキュリティ バインド要素の下のバインド スタックで IDuplexChannel インスタンスまたは IDuplexSessionChannel インスタンスの作成がサポートされている場合、双方向コントラクトに対して機能します。
セッション モード SCT は、セキュリティ バインド要素の下のバインド スタックで IDuplexChannel、 IDuplexSessionChannel、 IRequestChannel 、または IRequestSessionChannelインスタンスの作成がサポートされている場合、Request-Reply コントラクトに対して機能します。
セッション モード SCT は、セキュリティ バインド要素の下のバインド スタックで IDuplexChannel、 IDuplexSessionChannel、 IRequestChannel 、または IRequestSessionChannel インスタンスの作成がサポートされている場合、1 方向コントラクトに対して機能します。
標準バインディングからの派生
まったく新しいバインディング クラスを作成する代わりに、既存のシステム提供のバインディングのいずれかを拡張できる場合があります。 上記の場合と同様に、 CreateBindingElements メソッドと Scheme プロパティをオーバーライドする必要があります。