Share via


チュートリアル : サービスの説明とプロキシ クラスの生成のカスタマイズ

ASP.NET を使用して作成した Web サービスのサービスの説明とプロキシ クラスの生成は、サービス記述形式拡張 (SDFE: Service Description Format Extension) を作成してインストールすることにより拡張できます。具体的には、SDFE は XML 要素を Web サービス用の Web サービス記述言語 (WSDL: Web Services Description Language) ドキュメントとしてサービスの説明に追加したり、Web サービスと通信するメソッドにカスタム属性を追加したりできます。

SDFE は、特に SOAP 拡張機能を Web サービスとそのクライアントの両方で実行する必要がある場合に役立ちます。既定では、SOAP 拡張機能に関する情報は、サービスの説明および生成されたプロキシ クラスのどちらにも配置されません。クライアントとサーバーの両方で実行する必要がある SOAP 拡張機能の例として、暗号化 SOAP 拡張機能があります。サーバーで暗号化 SOAP 拡張機能を実行して SOAP 応答を暗号化する場合、クライアントではメッセージを復号化するための SOAP 拡張機能を実行している必要があります。SDFE では、サービスの説明に要素を追加して、SOAP 拡張機能を実行する必要があることをクライアントに通知することができます。また、SDFE によってプロキシ クラスの生成処理を拡張し、プロキシ クラスにカスタム属性を追加できます。これにより、クラスで SOAP 拡張機能を実行できます。このチュートリアルでは、次の作業を行う方法について説明します。

  1. サービスの説明に追加する XML を定義します。

  2. ServiceDescriptionFormatExtension クラスから派生する SDFE クラスを作成します。

  3. サービスの説明の生成処理を拡張するコードを記述します。

  4. プロキシ クラスの生成処理を拡張するコードを記述します。

  5. SDFE をクライアントとサーバーの両方で実行するように構成します。

XML の定義と SDFE クラスの作成

このチュートリアルのコード例には、SoapExtension クラスの YMLExtension に対する ServiceDescriptionFormateExtension クラスの YMLOperationBinding が含まれています。完全なコードは、「方法 : サービスの説明とプロキシ クラスの生成をカスタマイズする (サンプル コード)」に示されています。

サービスの説明に追加する XML を定義するには

  1. サービスの説明に追加する XML を決定します。

    サンプルの SDFE で XML 要素を追加するサービスの説明のコード例の一部を次に示します。具体的には、サンプルの SDFE では、WSDL ドキュメントのルート definitions 要素で XML 名前空間プレフィックス yml を宣言し、この名前空間をバインドする operation 要素にある yml:action 要素と子要素に適用します。

    <definitions ...
      xmlns:yml="https://www.contoso.com/yml" >
      ...
      <binding name="HelloWorldSoap" type="s0:HelloWorldSoap">
        <soap:binding transport="https://schemas.xmlsoap.org/soap/http"
                    style="document" /> 
          <operation name="SayHello">
            <soap:operation soapAction="http://tempuri.org/SayHello"
                        style="document" />
            <yml:action>
              <yml:Reverse>true</yml:Reverse> 
            </yml:action>
          </operation>
          ...
      </binding>
      ... 
    </definitions>
    
  2. ServiceDescriptionFormatExtension の派生クラスを作成します。

    Visual Studio .NET を使用する場合は、System.Web.Services アセンブリへの参照を追加します。また、System.Web.Services.Description 名前空間の using ステートメントまたは Imports ステートメントをファイルに追加します。

    ServiceDescriptionFormatExtension から派生する YMLOperationBinding クラスを作成するコードの例を次に示します。

    Public Class YMLOperationBinding
        Inherits ServiceDescriptionFormatExtension
    
    public class YMLOperationBinding : ServiceDescriptionFormatExtension
    
  3. クラスに XmlFormatExtensionAttribute を適用します。

    この属性は、サービスの説明の生成処理で SDFE が実行される段階 (拡張ポイント) を指定します。次の表は、定義された拡張ポイントと各ポイントで生成される WSDL XML 要素の一覧です。指定された拡張ポイントでは、対応する WSDL 要素が追加される要素の親になります。

    拡張ポイント 説明

    ServiceDescription

    WSDL ドキュメントの definitions ルート要素に相当します。

    Types

    definitions ルート要素内の types 要素に相当します。

    Binding

    definitions ルート要素内の binding 要素に相当します。

    OperationBinding

    binding 要素内の operation 要素に相当します。

    InputBinding

    operation 要素内の input 要素に相当します。

    OutputBinding

    operation 要素内の output 要素に相当します。

    FaultBinding

    operation 要素内の fault 要素に相当します。

    Port

    service 要素内の port 要素に相当します。

    Operation

    portType 要素内の operation 要素に相当します。

    クラスに XmlFormatExtensionAttribute を適用する場合は、サービスの説明に追加する XML 要素名と XML 要素を格納する XML 名前空間も指定します。

    YMLOperationBinding SDFE が OperationBinding 拡張ポイントでサービスの説明に <action xmlns="https://www.contoso.com/yml"> という名前の XML 要素を追加するように指定するコード例を次に示します。この例では、XML 名前空間 https://www.contoso.com/yml は、後でYMLOperationBinding.YMLNamespace フィールドがクラスに追加されるときに指定されます。

    <XmlFormatExtension("action", YMLOperationBinding.YMLNamespace, _
                        GetType(OperationBinding))> _
    Public Class YMLOperationBinding
        Inherits ServiceDescriptionFormatExtension
    
    [XmlFormatExtension("action", YMLOperationBinding.YMLNamespace,
                        typeof(OperationBinding))]
    public class YMLOperationBinding : ServiceDescriptionFormatExtension
    
  4. クラスに XmlFormatExtensionPrefixAttribute を適用して、XML 名前空間プレフィックスを SDFE が使用する XML 名前空間と関連付けることもできます。

    yml XML 名前空間プレフィックスをサービスの説明の definitions 要素にある https://www.contoso.com/yml 名前空間と関連付けるように指定するコード例を次に示します。また、プレフィックスは、SDFE で追加された要素内で名前空間の代わりに使用されます。したがって、手順 3 でサービスの説明に追加された XML 要素は、名前空間プレフィックスを使用することになります。このため、追加する要素は <action xmlns="https://www.contoso.com/yml"> ではなく <yml:action> になります。

    <XmlFormatExtension("action", YMLOperationBinding.YMLNamespace, _
                        GetType(OperationBinding)), _
     XmlFormatExtensionPrefix("yml", YMLOperationBinding.YMLNamespace)> _
    Public Class YMLOperationBinding
         Inherits ServiceDescriptionFormatExtension
    
    [XmlFormatExtension("action", YMLOperationBinding.YMLNamespace,
                        typeof(OperationBinding))]
    [XmlFormatExtensionPrefix("yml", YMLOperationBinding.YMLNamespace)]
    public class YMLOperationBinding : ServiceDescriptionFormatExtension 
    
  5. WSDL ドキュメントに追加する XML を表すクラスに、パブリック プロパティまたはフィールドを追加します。WSDL の <yml:Reverse>value</yml:Reverse> 要素にシリアル化される Reverse パブリック プロパティを追加するコード例を次に示します。

    Private _reverse As Boolean
    <XmlElement("Reverse")> _
    Public Property Reverse() As Boolean
       Get
         Return _reverse
       End Get
       Set(ByVal Value As Boolean)
          _reverse = Value
       End Set
    End Property 
    
    private Boolean reverse;
    [XmlElement("Reverse")]
    public Boolean Reverse 
    {
       get { return reverse; }
       set { reverse = value; }
    }
    

サービスの説明とクライアント プロキシの生成の拡張

WSDL 生成処理を拡張するには、SoapExtensionReflector クラスの派生クラスを作成します。クライアント プロキシ生成処理を拡張するには、SoapExtensionImporter クラスの派生クラスを作成します。

サービスの説明の生成処理を拡張するには

  1. SoapExtensionReflector の派生クラスを作成します。

    SoapExtensionReflector から派生する TraceReflector クラスを作成するコードの例を次に示します。

    Public Class YMLReflector
        Inherits SoapExtensionReflector
    
    public class YMLReflector : SoapExtensionReflector
    
  2. 各 Web サービス メソッドで、サービスの説明の生成中に呼び出される ReflectMethod メソッドをオーバーライドします。

    ReflectMethod をオーバーライドするコード例を次に示します。

    Public Overrides Sub ReflectMethod()
    
    public override void ReflectMethod()
    
  3. SoapExtensionReflector クラスの ReflectionContext プロパティの値を取得して、ProtocolReflector のインスタンスを取得します。

    ProtocolReflector のインスタンスは、現在の Web サービス メソッドの WSDL 生成処理の詳細を示します。ReflectionContext プロパティの値を取得するコード例を次に示します。

    Dim reflector As ProtocolReflector = ReflectionContext
    
    ProtocolReflector reflector = ReflectionContext;
    
  4. SDFE に値を指定するコードを追加します。

    Web サービス メソッドに YMLAttribute が適用されている場合に、サービスの説明に SDFE で定義された XML を追加するコード例を次に示します。

    Dim attr As YMLAttribute = _
        reflector.Method.GetCustomAttribute(GetType(YMLAttribute))
    ' If the YMLAttribute has been applied to this Web service
    ' method, adds the XML defined in the YMLOperationBinding class.
    If (Not attr Is Nothing) Then
       Dim yml As YMLOperationBinding = New YMLOperationBinding()
       yml.Reverse = Not attr.Disabled
    
    YMLAttribute attr = (YMLAttribute)
       reflector.Method.GetCustomAttribute(typeof(YMLAttribute));
    // If the YMLAttribute has been applied to this Web service 
    // method, adds the XML defined in the YMLOperationBinding class.
    if (attr != null) {
       YMLOperationBinding yml = new YMLOperationBinding();
       yml.Reverse = !(attr.Disabled);
    
  5. SDFE が拡張する拡張ポイントを表すプロパティの Extensions コレクションに SDFE を追加します。

    YmlOperationBinding SDFE を OperationBinding 拡張ポイントに追加するコード例を次に示します。

    reflector.OperationBinding.Extensions.Add(yml)
    
    reflector.OperationBinding.Extensions.Add(yml);
    

プロキシ クラスの生成処理を拡張するには

  1. SoapExtensionImporter から派生するクラスを作成します。

    Public Class YMLImporter
        Inherits SoapExtensionImporter
    
    public class YMLImporter : SoapExtensionImporter
    
  2. ImportMethod メソッドをオーバーライドします。

    ImportMethod は、サービスの説明で定義された各操作のプロキシ クラスの生成時に呼び出されます。ASP.NET を使用して作成した Web サービスでは、サービスの説明でサポートされている各プロトコルの操作に各 Web サービス メソッドが割り当てられます。

    Public Overrides Sub ImportMethod(ByVal metadata As _
                                      CodeAttributeDeclarationCollection)
    
    public override void ImportMethod(CodeAttributeDeclarationCollection
                                      metadata)   
    
  3. SoapExtensionImporterImportContext プロパティの値を取得して、SoapProtocolImporter のインスタンスを取得します。

    SoapProtocolImporter のインスタンスでは、Web サービス メソッドと通信している現在のメソッドのコード生成処理に関する詳細が示されます。ImportContext プロパティの値を取得するコード例を次に示します。

    Dim importer As SoapProtocolImporter = ImportContext
    
    SoapProtocolImporter importer = ImportContext;  
    
  4. Web サービスと通信するプロキシ クラスのメソッドに属性を適用する、または属性を変更するコードを追加します。

    ImportMethodCodeAttributeDeclarationCollection 型の引数を 1 つ渡します。これは、Web サービス メソッドと通信するメソッドに適用される属性のコレクションを表します。YMLAttribute をコレクションに追加し、サービスの説明に適切な XML が含まれている場合に YML SOAP 拡張機能がメソッドと共に実行されるようにするコード例を次に示します。

    ' Checks whether the XML specified in the YMLOperationBinding is in the
    ' service description.
    Dim yml As YMLOperationBinding = _
      importer.OperationBinding.Extensions.Find( _
      GetType(YMLOperationBinding))
    If (Not yml Is Nothing) Then
       ' Only applies the YMLAttribute to the method when the XML should
       ' be reversed.
       If (yml.Reverse) Then
          Dim attr As CodeAttributeDeclaration = New _
            CodeAttributeDeclaration(GetType(YMLAttribute).FullName)
          attr.Arguments.Add(New CodeAttributeArgument(New _
               CodePrimitiveExpression(True)))
          metadata.Add(attr)
       End If
    End If
    
    // Checks whether the XML specified in the YMLOperationBinding is
    // in the service description.
    YMLOperationBinding yml = (YMLOperationBinding)
       importer.OperationBinding.Extensions.Find(
       typeof(YMLOperationBinding));
    if (yml != null)
    {
       // Only applies the YMLAttribute to the method when the XML should
       // be reversed.
       if (yml.Reverse)
       {
         CodeAttributeDeclaration attr = new
            CodeAttributeDeclaration(typeof(YMLAttribute).FullName);
         attr.Arguments.Add(new CodeAttributeArgument(new
            CodePrimitiveExpression(true)));
         metadata.Add(attr);
       }
    }
    

SDFE の構成

SDFE を構成するには、Web サービスとクライアントの両方で構成ファイルを編集する必要があります。

Web サービスと共に実行されるように SDFE を構成するには

  1. SDFE を格納するアセンブリをアクセス可能なフォルダにインストールします。

    複数の Web アプリケーションで SDFE が必要な場合以外は、Web サービスをホストする Web アプリケーションの \Bin フォルダに SDFE をインストールします。

  2. Web アプリケーションの Web.config ファイルに、add 要素を持つ <serviceDescriptionFormatExtensionTypes> 要素 要素を追加し、SDFE の名前と SDFE を格納するアセンブリを指定します。

    Web.config ファイルの影響を受けるすべての Web サービスと共に Sample.YMLOperationBinding SDFE を実行するように構成するコード例を次に示します。add 要素は全体を 1 行で記述する必要があります。

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
       </webServices>
    </system.web>
    
  3. Web アプリケーションの Web.config ファイルに、add 要素を持つ <soapExtensionReflectorTypes> 要素 要素を追加し、サービスの説明の生成処理を拡張するクラスの名前とアセンブリを指定します。

    Web.config ファイルの影響を受けるすべての Web サービスと共に Sample.YMLReflector を実行するように構成するコード例を次に示します。add 要素は全体を 1 行で記述する必要があります。

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
          <soapExtensionReflectorTypes>
             <add type="Sample.YMLReflector,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </soapExtensionReflectorTypes>
       </webServices>
    </system.web>
    

Web サービス クライアントと共に実行されるように SDFE を構成するには

  1. SDFE を格納するアセンブリをグローバル アセンブリ キャッシュにインストールします。

    インストールするには、厳密な名前のアセンブリである必要があります。厳密な名前のアセンブリを作成する方法の詳細については、「厳密な名前付きアセンブリの作成と使用」を参照してください。アセンブリのインストール方法の詳細については、「グローバル アセンブリ キャッシュにアセンブリをインストールする」を参照してください。

  2. Machine.config ファイルに、add 要素を持つ <serviceDescriptionFormatExtensionTypes> 要素 要素を追加し、SDFE の名前と SDFE を格納するアセンブリを指定します。

    コンピュータで、Web サービスに対してプロキシ クラスが生成されるたびに Sample.YMLOperationBinding SDFE を実行するように構成するコード例を次に示します。

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
       </webServices>
    </system.web>
    
  3. Machine.config ファイルに add 要素を持つ <soapExtensionImporterTypes> 要素 要素を追加し、プロキシ クラスの生成処理を拡張するクラスの名前とアセンブリを指定します。

    コンピュータで、Web サービスに対してプロキシ クラスが生成されるたびに Sample.YMLImporter を実行するように構成するコード例を次に示します。

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
          <soapExtensionImporterTypes>
             <add type="Sample.YMLImporter,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </soapExtensionImporterTypes>
       </webServices>
    </system.web>
    
    Noteメモ :

    プロキシ クラスで生成されたメソッドは、Web サービスと通信するクライアント アプリケーションで使用されるため、クライアント アプリケーションに通知されないアセンブリにある属性を SDFE が追加すると、コンパイラ エラーが発生します。コンパイラ エラーを解決するには、次の手順を実行します。Visual Studio .NET を使用している場合は、属性を格納するアセンブリへの参照を追加します。コマンド ライン コンパイルを使用している場合は、コンパイラのコマンド ラインにアセンブリを追加します。

関連項目

タスク

チュートリアル : サービスの説明とプロキシ クラスの生成のカスタマイズ

参照

XmlFormatExtensionAttribute
XmlFormatExtensionPrefixAttribute
XmlFormatExtensionPointAttribute

概念

SOAP 拡張機能を使用した SOAP メッセージの変更

Footer image

Copyright © 2007 by Microsoft Corporation.All rights reserved.