연습: 서비스 설명 및 프록시 클래스의 생성 사용자 지정

이 항목은 레거시 기술과 관련된 것입니다. 이제 XML Web services와 XML Web services 클라이언트는 다음을 사용하여 만들어야 합니다. Windows Communication Foundation.

SDFE(서비스 설명 형식 확장)를 만든 후 설치하여 ASP.NET으로 만든 웹 서비스의 프록시 클래스와 서비스 설명의 생성을 확장할 수 있습니다. 특히 SDFE는 서비스 설명(웹 서비스에 대한 WSDL(웹 서비스 기술 언어))에 XML 요소를 추가하고 웹 서비스와 통신하는 메서드에 사용자 지정 특성을 추가할 수 있습니다.

SDFE는 웹 서비스와 클라이언트 모두에서 SOAP 확장을 실행해야 하는 경우에 특히 유용합니다. 기본적으로 서비스 설명이나 생성된 프록시 클래스에는 SOAP 확장에 대한 정보가 없습니다. 클라이언트와 서버 모두에서 실행되어야 하는 SOAP 확장의 예로는 암호화 SOAP 확장을 들 수 있습니다. 서버에서 암호화 SOAP 확장을 실행하여 SOAP 응답을 암호화할 경우 클라이언트가 메시지를 해독하려면 SOAP 확장을 실행해야 합니다. SDFE는 SOAP 확장을 실행해야 한다고 클라이언트에 알려주는 요소를 서비스 설명에 추가할 수 있습니다. 또한 프록시 클래스 생성 프로세스를 확장하여 프록시 클래스에 사용자 지정 특성을 추가할 수 있으며 그러면 클래스에서 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 요소를 포함합니다.

    다음 코드 예제에서는 OperationBinding 확장 지점에서 YMLOperationBinding SDFE가 <action xmlns="https://www.contoso.com/yml"> XML 요소를 서비스 설명에 추가하도록 지정합니다. 이 예제의 경우 YMLOperationBinding.YMLNamespace 필드가 클래스에 추가된 후에 https://www.contoso.com/yml XML 네임스페이스가 지정됩니다.

    <XmlFormatExtension("action", YMLOperationBinding.YMLNamespace, _
                        GetType(OperationBinding))> _
    Public Class YMLOperationBinding
        Inherits ServiceDescriptionFormatExtension
    
    [XmlFormatExtension("action", YMLOperationBinding.YMLNamespace,
                        typeof(OperationBinding))]
    public class YMLOperationBinding : ServiceDescriptionFormatExtension
    
  4. 필요에 따라 XmlFormatExtensionPrefixAttribute를 클래스에 선택적으로 적용하여 SDFE에 사용되는 XML 네임스페이스에 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을 나타내는 클래스에 public 속성 및 필드를 추가합니다. 다음 코드 예제에서는 WSDL의 <yml:Reverse>value</yml:Reverse> 요소로 serialize되는 Reverse public 속성을 추가합니다.

    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. 각 웹 서비스 메서드에 대한 서비스 설명을 생성하는 중에 호출되는 ReflectMethod 메서드를 재정의합니다.

    다음 코드 예제에서는 ReflectMethod를 재정의합니다.

    Public Overrides Sub ReflectMethod()
    
    public override void ReflectMethod()
    
  3. SoapExtensionReflector 클래스의 ReflectionContext 속성 값을 가져와서 ProtocolReflector 인스턴스를 가져옵니다.

    ProtocolReflector 인스턴스는 현재 웹 서비스 메서드의 WSDL 생성 프로세스 관련 정보를 제공합니다. 다음 코드 예제에서는 ReflectionContext 속성의 값을 가져옵니다.

    Dim reflector As ProtocolReflector = ReflectionContext
    
    ProtocolReflector reflector = ReflectionContext;
    
  4. SDFE를 채우기 위한 코드를 추가합니다.

    다음 코드 예제에서는 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을 사용하여 만든 웹 서비스의 경우 서비스 설명에서 지원되는 각 프로토콜에 대한 작업에 각 웹 서비스 메서드가 매핑됩니다.

    Public Overrides Sub ImportMethod(ByVal metadata As _
                                      CodeAttributeDeclarationCollection)
    
    public override void ImportMethod(CodeAttributeDeclarationCollection
                                      metadata)   
    
  3. SoapExtensionImporterImportContext 속성 값을 가져와서 SoapProtocolImporter의 인스턴스를 가져옵니다.

    SoapProtocolImporter 인스턴스는 웹 서비스 메서드와 통신하는 현재 메서드에 대한 코드 생성 프로세스 관련 정보를 제공합니다. 다음 코드 예제에서는 ImportContext 속성의 값을 가져옵니다.

    Dim importer As SoapProtocolImporter = ImportContext
    
    SoapProtocolImporter importer = ImportContext;  
    
  4. 웹 서비스와 통신하는 프록시 클래스의 메서드에 특성을 적용하거나 수정할 코드를 추가합니다.

    ImportMethod는 웹 서비스 메서드와 통신하는 메서드에 적용되는 특성 컬렉션을 나타내는 CodeAttributeDeclarationCollection 형식 인수로 전달됩니다. 다음 코드 예제에서는 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를 구성하려면 웹 서비스와 클라이언트 모두에서 구성 파일을 편집해야 합니다.

웹 서비스와 연동되도록 SDFE를 구성하려면

  1. 액세스할 수 있는 폴더에 SDFE를 포함하는 어셈블리를 설치합니다.

    SDFE가 여러 웹 응용 프로그램에 필요한 경우가 아니면 웹 서비스를 호스팅하는 웹 응용 프로그램의 \bin 폴더에 SDFE를 설치합니다.

  2. add 요소를 사용하여 <serviceDescriptionFormatExtensionTypes> 요소 요소를 추가하고, SDFE를 포함하는 이름 및 어셈블리를 웹 응용 프로그램의 Web.config 파일에 지정합니다.

    다음 코드 예제에서는 Web.config 파일의 영향을 받는 모든 웹 서비스와 연동되도록 Sample.YMLOperationBinding SDFE를 구성합니다. 전체 add 요소는 줄 바꿈 없이 한 줄에 표시되어야 합니다.

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
       </webServices>
    </system.web>
    
  3. add 요소를 사용하여 <soapExtensionReflectorTypes> 요소 요소를 추가하고, 서비스 설명 생성 프로세스를 확장하는 클래스의 이름과 어셈블리를 웹 응용 프로그램의 Web.config 파일에 지정합니다.

    다음 코드 예제에서는 Web.config 파일의 영향을 받는 모든 웹 서비스와 연동되도록 Sample.YMLReflector를 구성합니다. 전체 add 요소는 줄 바꿈 없이 한 줄에 표시되어야 합니다.

    <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>
    

웹 서비스 클라이언트와 연동되도록 SDFE를 구성하려면

  1. SDFE를 포함하는 어셈블리를 전역 어셈블리 캐시에 설치합니다.

    어셈블리를 설치하려면 어셈블리의 이름이 강력한 이름이어야 합니다. 강력한 이름의 어셈블리를 만드는 방법에 대한 자세한 내용은 강력한 이름의 어셈블리 만들기 및 사용을 참조하십시오. 어셈블리 설치에 대한 자세한 내용은 전역 어셈블리 캐시에 어셈블리 설치를 참조하십시오.

  2. add 요소를 사용하여 <serviceDescriptionFormatExtensionTypes> 요소 요소를 추가하고 SDFE를 포함하는 이름과 어셈블리를 Machine.config 파일에 지정합니다.

    다음 코드 예제에서는 웹 서비스에 대한 프록시 클래스가 생성될 때마다 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. add 요소를 사용하여 <soapExtensionImporterTypes> 요소 요소를 추가하고 프록시 클래스 생성 프로세스를 확장하는 클래스의 이름과 어셈블리를 Machine.config 파일에 지정합니다.

    다음 코드 예제에서는 웹 서비스에 대한 프록시 클래스가 생성될 때마다 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>
    
    x4s9z3yc.note(ko-kr,VS.100).gif참고:
    프록시 클래스에 생성된 메서드는 웹 서비스와 통신하는 클라이언트 응용 프로그램에서 사용됩니다. 따라서 SDFE가 클라이언트 응용 프로그램에 알려지지 않은 어셈블리에 있는 특성을 추가하면 컴파일러 오류가 발생합니다. 컴파일러 오류를 해결하려면 특성을 포함하는 어셈블리에 대한 참조를 추가하거나(Visual Studio .NET을 사용하는 경우) 컴파일러 명령줄에 어셈블리를 추가합니다(명령줄 컴파일을 사용하는 경우).

참고 항목

작업

연습: 서비스 설명 및 프록시 클래스의 생성 사용자 지정

참조

XmlFormatExtensionAttribute
XmlFormatExtensionPrefixAttribute
XmlFormatExtensionPointAttribute

개념

SOAP 확장을 사용하는 SOAP 메시지 수정