Пошаговое руководство. Настройка процесса создания описаний служб и прокси-классов

Этот раздел посвящен технологии прежних версий. Веб-службы XML и клиенты веб-служб XML должны создаваться с использованием Windows Communication Foundation.

Процесс создания описания службы и прокси-классов веб-службы, созданной с помощью ASP.NET, можно расширить посредством создания и установки расширения формата описания службы (SDFE). В частности, SDFE может добавлять XML-элементы в описание службы (WSDL-документ для веб-службы) и настраиваемые атрибуты в метод, обменивающийся данными с веб-службой.

Расширения SDFE особенно полезны, когда расширение SOAP должно выполняться и с веб-службой, и с ее клиентами; по умолчанию никаких сведений о расширениях SOAP ни в описании службы, ни в созданных для нее прокси-классах не размещается. Примером расширения SOAP, которое должно выполняться как на клиенте, так и на сервере, является расширение SOAP для шифрования. Если расширение SOAP для шифрования выполняется на сервере для шифрования ответа SOAP, клиент должен иметь расширение SOAP для расшифровки сообщения. SDFE может добавлять элементы в описание службы для информирования клиентов о необходимости выполнения расширения SOAP, а также расширять процесс создания прокси-класса для добавления в прокси-класс настраиваемого атрибута, который заставляет класс выполнять расширение SOAP. В этом пошаговом руководстве описаны следующие задачи.

  1. Определение XML-элементов для добавления в описание службы.

  2. Создание класса SDFE, производного от класса ServiceDescriptionFormatExtension.

  3. Написание кода, дополняющего процесс создания описания службы.

  4. Написание кода, дополняющего процесс создания прокси-класса.

  5. Настройка SDFE для выполнения и на клиенте и на сервере.

Определение XML-кода и создание класса SDFE

В образцах кода из этого пошагового руководства участвует YMLOperationBinding класса ServiceDescriptionFormateExtension для YMLExtension класса SoapExtension. Полностью код представлен в разделе Как настроить создание описаний служб и прокси-классов. (образец кода).

Определение элементов XML для добавления в описание службы

  1. Выберите элементы XML для добавления в описание службы.

    Следующий пример кода представляет собой часть описания службы, в которую образец SDFE добавляет элементы XML. В частности, образец SDFE объявляет префикс пространства имен XML yml в корневом элементе definitions WSDL-документа и применяет это пространство имен к элементу yml:action (и дочерним элементам), которые находятся в элементах operation привязки.

    <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. Добавьте также в файл оператор using или Imports для пространства имен System.Web.Services.Description.

    В следующем примере кода создается класс YMLOperationBinding, наследуемый от класса ServiceDescriptionFormatExtension.

    Public Class YMLOperationBinding
        Inherits ServiceDescriptionFormatExtension
    
    public class YMLOperationBinding : ServiceDescriptionFormatExtension
    
  3. Примените для созданного класса атрибут XmlFormatExtensionAttribute.

    Этот атрибут задает стадию процесса создания описания службы, называемую точкой расширения, в которой выполняется SDFE. В следующей таблице перечислены определенные точки расширения и элементы XML WSDL, созданные в каждой точке. Для заданной точки расширения соответствующий элемент WSDL становится родительским элементом добавляемого элемента.

    Точка расширения Описание

    ServiceDescription

    Соответствует корневому элементу definitions документа WSDL.

    Types

    Соответствует элементу types, содержащемуся в корневом элементе definitions.

    Binding

    Соответствует элементу binding, содержащемуся в корневом элементе definitions.

    OperationBinding

    Соответствует элементу operation, содержащемуся в элементе binding.

    InputBinding

    Соответствует элементу input, содержащемуся в элементе operation.

    OutputBinding

    Соответствует элементу output, содержащемуся в элементе operation.

    FaultBinding

    Соответствует элементу fault, содержащемуся в элементе operation.

    Port

    Соответствует элементу port, содержащемуся в элементе service.

    Operation

    Соответствует элементу operation, содержащемуся в элементе portType.

    При применении атрибута XmlFormatExtensionAttribute для класса можно также задать имя элемента XML и пространство имен XML, к которому должны относиться элементы XML, добавляемые в описание службы.

    В следующем примере кода указывается, что SDFE YMLOperationBinding добавляет элемент XML с именем <action xmlns="https://www.contoso.com/yml"> в описание службы в точке расширения OperationBinding. Для этого примера пространство имен 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 с пространством имен XML, используемым расширением SDFE.

    В следующем примере кода указывается, что префикс пространства имен XML yml связывается с пространством имен https://www.contoso.com/yml в элементе definitions описания службы. Кроме того, этот префикс используется в элементах, добавляемых расширением SDFE, вместо пространства имен. Следовательно, элемент XML, добавленный в описание службы на шаге 3, теперь использует префикс пространства имен и, таким образом, добавленным элементом является элемент <yml:action> вместо элемента <action xmlns="https://www.contoso.com/yml">.

    <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. Добавьте открытые свойства и поля в класс, представляющий XML-код, который должен быть добавлен в WSDL-документ. В следующем примере кода добавляется открытое свойство Reverse, которое сериализуется в элемент <yml:Reverse>value</yml:Reverse> документа WSDL.

    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.

    В следующем примере кода создается класс TraceReflector, наследуемый от класса SoapExtensionReflector.

    Public Class YMLReflector
        Inherits SoapExtensionReflector
    
    public class YMLReflector : SoapExtensionReflector
    
  2. Переопределите метод ReflectMethod, вызываемый в процессе создания описания службы, для каждого метода веб-службы.

    В следующем примере кода переопределяется метод ReflectMethod.

    Public Overrides Sub ReflectMethod()
    
    public override void ReflectMethod()
    
  3. Получите значение свойства ReflectionContext класса SoapExtensionReflector, чтобы получить экземпляр класса ProtocolReflector.

    Экземпляр класса ProtocolReflector предоставляет подробные сведения о процессе создания WSDL-документа для текущего метода веб-службы. В следующем примере кода получается значение свойства ReflectionContext.

    Dim reflector As ProtocolReflector = ReflectionContext
    
    ProtocolReflector reflector = ReflectionContext;
    
  4. Добавьте код для заполнения SDFE.

    В следующем примере кода в описание службы добавляется элемент XML, определенный расширением SDFE, если для метода веб-службы применяется атрибут YMLAttribute .

    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.

    В следующем примере кода добавляется SDFE YmlOperationBinding в точку расширения 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. Получите значение свойства ImportContext класса SoapExtensionImporter, чтобы получить экземпляр класса SoapProtocolImporter.

    Экземпляр класса SoapProtocolImporter предоставляет подробные сведения о процессе создания кода для текущего метода, взаимодействующего с методом веб-службы. В следующем примере кода получается значение свойства ImportContext.

    Dim importer As SoapProtocolImporter = ImportContext
    
    SoapProtocolImporter importer = ImportContext;  
    
  4. Добавьте код, чтобы применить или изменить атрибуты для метода в прокси-классе, который взаимодействует с веб-службой.

    Метод ImportMethod осуществляет передачу в одном аргументе типа CodeAttributeDeclarationCollection, который представляет коллекцию атрибутов, применяемых для метода, взаимодействующего с методом веб-службы. В следующем примере кода в коллекцию добавляется атрибут YMLAttribute, который приводит к выполнению расширения SOAP YML с методом, когда описание службы содержит соответствующий элемент XML.

    ' 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 не требуется для нескольких веб-приложений, установите SDFE в папку \bin веб-приложения, в котором размещается веб-служба.

  2. Добавьте в файл Web.config для веб-приложения элемент Элемент <serviceDescriptionFormatExtensionTypes> с элементом add и укажите имя и сборку, содержащую SDFE.

    В следующем примере кода настраивается SDFE Sample.YMLOperationBinding для выполнения со всеми веб-службами, затрагиваемыми файлом Web.config. Весь элемент add должен находиться на одной строке.

    <system.web>
       <webServices>
          <serviceDescriptionFormatExtensionTypes>
             <add type="Sample.YMLOperationBinding,Yml,
                  Version=1.0.0.0,Culture=neutral,
                  PublicKeyToken=6e55c64c6b897b30"/>
          </serviceDescriptionFormatExtensionTypes>
       </webServices>
    </system.web>
    
  3. Добавьте в файл Web.config для веб-приложения элемент Элемент <soapExtensionReflectorTypes> с элементом add и укажите имя и сборку класса, расширяющего процесс создания описания службы.

    В следующем примере кода настраивается Sample.YMLReflector для выполнения со всеми веб-службами, затрагиваемыми файлом Web.config. Весь элемент 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. Добавьте в файл Machine.config элемент Элемент <serviceDescriptionFormatExtensionTypes> с элементом add и укажите имя и сборку, содержащую SDFE.

    В следующем примере кода настраивается SDFE Sample.YMLOperationBinding для выполнения всякий раз, когда для веб-служб на компьютере создаются прокси-классы.

    <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 элемент Элемент <soapExtensionImporterTypes> с элементом add и укажите имя и сборку класса, расширяющего процесс создания прокси-класса.

    В следующем примере кода настраивается 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(ru-ru,VS.100).gifПримечание
    Метод, созданный в прокси-классе, используется клиентским приложением, взаимодействующим с веб-службой. Поэтому, если SDFE добавляет атрибут, находящийся в сборке, о которой клиентское приложение не уведомлено, выдается ошибка компилятора. Чтобы устранить эту ошибку, при использовании Visual Studio .NET добавьте ссылку на сборку, которая содержит этот атрибут, а при использовании компиляции из командной строки добавьте сборку в командную строку компилятора.

См. также

Задачи

Пошаговое руководство. Настройка процесса создания описаний служб и прокси-классов

Справочник

XmlFormatExtensionAttribute
XmlFormatExtensionPrefixAttribute
XmlFormatExtensionPointAttribute

Основные понятия

Изменение сообщений SOAP с помощью расширений SOAP