エンドポイント アドレスの指定
Windows Communication Foundation (WCF) サービスを使用して行われるすべての通信では、エンドポイントが使用されます。各 ServiceEndpoint は、Address、Binding、および Contract で構成されます。コントラクトでは、使用できる操作を指定します。バインディングでは、サービスとの通信方法を指定し、アドレスでは、サービスの場所を指定します。各エンドポイントには、一意のアドレスを設定する必要があります。エンドポイント アドレスは、EndpointAddress クラスによって表します。このクラスは、サービスのアドレスを表す URI (Uniform Resource Identifier)、サービスのセキュリティ ID を表す Identity、およびオプションの Headers のコレクションで構成されます。オプション ヘッダーは、エンドポイントの識別または対話のために、より詳細なアドレス指定情報を提供します。たとえば、ヘッダーを使用して、受信メッセージの処理方法や、エンドポイントからの応答メッセージの送信先を指定できるほか、複数のサービス インスタンスが使用できる場合に、特定ユーザーからの受信メッセージの処理に使用するインスタンスを指定できます。
エンドポイント アドレスの定義
WCF の EndpointAddress は、WS-Addressing 仕様で定義されているエンドポイント参照 (EPR) をモデル化します。
ほとんどのトランスポートの URI アドレスは、4 つの部分から構成されます。たとえば、"http://www.fabrikam.com:322/mathservice.svc/secureEndpoint" という URI は、次の 4 つの部分から構成されます。
- スキーム : http:
- コンピュータ : www.fabrikam.com
- (省略可能) ポート : 322
- パス : /mathservice.svc/secureEndpoint
EPR モデルの一部では、各エンドポイント参照は、追加の識別情報を追加する複数の参照パラメータを伝達できます。WCF では、これらの参照パラメータは AddressHeader クラスのインスタンスとしてモデル化されます。
サービスのエンドポイント アドレスはコードを使用して強制的に指定するか、構成を介して宣言として指定できます。設置済みサービスのバインディングおよびアドレスは一般的に、サービスの開発中に使用されるものとは異なるので、コード内でエンドポイントを定義することは通常、実用的ではありません。一般に、サービス エンドポイントの定義にはコードではなく、構成を使用する方がより実用的です。バインディング情報とアドレス情報をコードに含めないことで、変更時にアプリケーションの再コンパイルや再展開を行う必要がなくなります。
WCF でサービスのエンドポイント アドレスを指定するには 2 つの方法があります。サービスに関連付けられた各エンドポイントに対して絶対アドレスを指定する方法と、ServiceHost のベース アドレスを設定して、このベース アドレスから相対的に定義されるアドレスをサービスに関連付けられた各エンドポイントに対して指定する方法です。サービスのエンドポイント アドレスを指定するには、構成とコードのいずれかで、これらの各方法を使用します。相対アドレスを指定しない場合、サービスはベース アドレスを使用します。サービスに対して複数のベース アドレスを設定することもできますが、サービスが各トランスポートに対して設定できるベース アドレスは 1 つに限られます。複数のエンドポイントがある場合、各エンドポイントには異なるバインディングで構成されるため、それぞれのアドレスは一意になります。異なるコントラクトで同じバインディングを使用するエンドポイントは同じアドレスを使用できます。
IIS でホストする場合、ユーザーは ServiceHost インスタンスを管理できません。IIS でホストしているサービスでは、サービスの .svc ファイルで指定されているアドレスが常にベース アドレスになります。そのため、IIS でホストされるサービスのエンドポイントでは、相対エンドポイント アドレスを使用する必要があります。完全修飾されたエンドポイント アドレスを指定すると、サービスの展開時にエラーとなる可能性があります。詳細な情報については、次のページを参照してください。 「インターネット インフォメーション サービスでホストされる WCF サービスの配置」を参照してください。
構成によるエンドポイント アドレスの定義
構成ファイルでエンドポイントを定義するには、<endpoint> 要素を使用します。
Open メソッドが呼び出されると (このメソッドは、ホスト アプリケーションがサービスを開始しようとしたときに呼び出されます)、システムは、"UE.Samples.HelloWorld" を指定する name 属性を持つ <service> 要素を検索します。その <service> 要素が見つかった場合、システムは、構成ファイルにあるエンドポイント定義を使用して、指定されたクラスを読み込み、エンドポイントを作成します。このしくみによって、2 行のコードでサービスを読み込んで開始でき、バインディングとアドレス指定情報をコード外に維持することができます。この方法の利点は、アプリケーションを再度コンパイルしたり、展開したりすることなく、この 2 つの情報を変更できる点です。
オプション ヘッダーは <headers> elementで宣言します。次に示す例では、構成ファイルでサービスのエンドポイントを指定するための要素で、2 つのヘッダー (http://tempuri1.org/ からの "Gold" クライアントと http://tempuri2.org/ からの "Standard" クライアント) を識別しています。このサービスを呼び出すクライアントの構成ファイルには、適切な <headers> elementが記述されている必要があります。
ヘッダーは、(上記のように) エンドポイントのすべてのメッセージに対してではなく、個別のメッセージに設定できます。この設定は、次の例で示すように、OperationContextScope を使用してクライアント アプリケーションに新しいコンテキストを作成し、送信メッセージにカスタム ヘッダーを追加することで行います。
メタデータ内のエンドポイント アドレス
Web サービス記述言語 (WSDL) では、エンドポイント アドレスは、対応するエンドポイントの wsdl:port 要素内で WS-Addressing の EndpointReference (EPR) 要素として表されます。EPR には、エンドポイントのアドレスのほかに、アドレスのすべてのプロパティが含まれます。wsdl:port 内にある EPR では、次の例に示すように soap:Address を置き換えるので注意してください。
コードによるエンドポイント アドレスの定義
エンドポイント アドレスは、コードで EndpointAddress クラスを使用して作成できます。エンドポイント アドレスに指定する URI は、完全修飾パスまたはサービスのベース アドレスを基準にしたパスです。EndpointAddress クラスのインスタンスを作成し、そのインスタンスを、サービスをホストする ServiceHost インスタンスに追加する方法を次のコードに示します。
次の例は、コードで完全なエンドポイント アドレスを指定する方法を示しています。
次の例は、サービス ホストのベース アドレスに相対アドレス ("MyService") を追加する方法を示しています。
メモ : |
---|
ServiceHostBase の OnOpening メソッドの後で、サービス アプリケーションの ServiceDescription の各プロパティを変更しないでください。このメソッドの後で変更すると、ServiceHostBase および ServiceHost の Credentials プロパティや AddServiceEndpoint メソッドなどの一部のメンバは例外をスローします。変更を許可するメンバもありますが、結果は未定義の状態になります。 同様に、クライアントで、ChannelFactory の OnOpening 呼び出しの後で、ServiceEndpoint 値を変更しないでください。この呼び出しの後で変更すると、Credentials プロパティは例外をスローします。その他のクライアント記述値は、エラーを発生させずに変更できますが、結果は未定義の状態になります。 サービスとクライアントのどちらの場合も、Open の呼び出しの前に記述を変更することをお勧めします。 |