DIRECTUM и WEB-сервисы (часть 3)

14 5

В предыдущих двух частях мы рассмотрели, как можно обращаться к WEB-сервисам из DIRECTUM и подключать утилиту трассировки SOAP-вызовов для анализа ответов получаемых от сервера. Приведенные в материале примеры замечательно работают, пока у пользователя есть доступ в интернет. А как быть, если в организации пользователям запрещен доступ в интернет или мы хотим чтобы все подключения к сервису выполнялись от имени какого-нибудь специально отведенного для этого пользователя? В этом нам поможет свойство ConnectorProperty: 

  WSDLFileNameURL = "http://www.cbr.ru/dailyinfowebserv/dailyinfo.asmx?WSDL"

  // Инициализация подключения к сервису
  SoapClient = CreateObject("MSSOAP.SoapClient30")
  SoapClient.MSSoapInit(WSDLFileNameURL; "DailyInfo"; "DailyInfoSoap")
  SoapClient.ConnectorProperty("EndPointURL") = WSDLFileNameURL
  SoapClient.ConnectorProperty("ProxyServer") = ProxyServer
  SoapClient.ConnectorProperty("ProxyUser")  = UserName
  SoapClient.ConnectorProperty("ProxyPassword")  = Password
  
  Rez = SoapClient.GetCursOnDateXML(Сейчас())
  
// Обработка результата
…

 Если строчки

  SoapClient.ConnectorProperty("ProxyServer") = ProxyServer
  SoapClient.ConnectorProperty("ProxyUser")  = UserName
  SoapClient.ConnectorProperty("ProxyPassword")  = Password

заменить на

  SoapClient.ConnectorProperty("ProxyServer") = ""

 

то для подключения к прокси-серверу будут использованы настройки из Internet Explorer для текущего пользователя.

Если сам WEB-сервис тоже требует авторизации, то тогда к нашему примеру надо будет добавить код:

  SoapClient.ConnectorProperty("AuthUser") = UserName
  SoapClient.ConnectorProperty("AuthPassword") = Password
  SoapClient.ConnectorProperty("WinHTTPAuthScheme") = 1

где свойство WinHTTPAuthScheme может принимать значения:

  • 0x1 - basic authentication
  • 0x2 - ntlm auth
  • 0x8 - digest auth
  • 0x10 - negotiate auth

Значение по умолчанию 0x12 (ntlm and negotiate).

Если мы хотим использовать шифрование SSL, то необходимо добавить свойство:

  SoapClient.ConnectorProperty("UseSSL") = True

Более подробную информацию можно посмотреть в справке Microsoft SOAP Toolkit 3.0.

В заключение приведу пример еще одного способа обращения к WEB-сервису Центрального банка Российской Федерации. Будем использовать все тот же метод GetCursOnDateXML, но запрос будем формировать вручную:

  WSDLFileName = "http://www.cbr.ru/dailyinfowebserv/dailyinfo.asmx?WSDL"

  Connector = CreateObject("MSSOAP.HttpConnector30")
  Connector.Property("EndPointURL") = WSDLFileName
  Connector.Property("ProxyServer") = ProxyServer
  Connector.Property("ProxyUser")  = UserName
  Connector.Property("ProxyPassword")  = Password
  Connector.Connect
  Connector.Property("SoapAction") = "http://web.cbr.ru/GetCursOnDateXML"
  Connector.BeginMessage

  Serializer = CreateObject("MSSOAP.SoapSerializer30")
  Serializer.Init(Connector.InputStream)
  Serializer.StartEnvelope
  Serializer.StartBody
  Serializer.StartElement("GetCursOnDateXML";"http://web.cbr.ru/")
  Serializer.StartElement("On_date";"http://web.cbr.ru/")
  Serializer.WriteString(FormatDateTimeForXML(Сейчас()))
  Serializer.EndElement
  Serializer.EndElement
  Serializer.EndBody
  Serializer.EndEnvelope
    
  Connector.EndMessage

  Reader = CreateObject("MSSOAP.SoapReader30")
  Reader.Load(Connector.OutputStream)
    
  if Assigned(Reader.Fault)
    MessageBox(ERROR_CAPTION;Reader.FaultString.Text)
  else
    XMLDoc = CreateObject("MSXml.DomDocument")
    XMLDoc.LoadXML(Reader.Body.xml)
    // Получим дату курсов валют
    ValuteData = XMLDoc.selectSingleNode("//GetCursOnDateXMLResult/ValuteData")
    OnDate = ValuteData.Attributes.getNamedItem("OnDate").Value
    Year = Copy(OnDate;1;4)
    Month = Copy(OnDate;5;2)
    Day = Copy(OnDate;7;2)
    Data = Format("%s.%s.%s";ArrayOf(Day;Month;Year))
    Str = "Курсы валют на "&Data&" составляют:"&CR
    // Получим дочерние элементы
    ChildNodes = ValuteData.childNodes
    // Количество дочерних элементов
    ChildNodesCount = ChildNodes.Length
    Count = 0
    // переберем все дочерние элементы и сформируем результирующую строку
    while Count < ChildNodesCount
      Node = ChildNodes.Item(Count)
      NodeCurs = Node.childNodes
      NodeCursCount = NodeCurs.Length
      ChildCount = 0
      Str2 = ""
      while ChildCount < NodeCursCount
        if NodeCurs.Item(ChildCount).nodeName == 'Vname'
          Vname = Trim(NodeCurs.Item(ChildCount).Text)
        endif
        if NodeCurs.Item(ChildCount).nodeName == 'Vnom'
          Vnom = NodeCurs.Item(ChildCount).Text
        endif
        if NodeCurs.Item(ChildCount).nodeName == 'Vcurs'
          Vcurs = NodeCurs.Item(ChildCount).Text
        endif
        if NodeCurs.Item(ChildCount).nodeName == 'VchCode'
          VchCode = NodeCurs.Item(ChildCount).Text
        endif
        ChildCount = ChildCount + 1
      endwhile
      Str2 = Format("%s: %s руб = %s %s";ArrayOf(Vname; Vcurs; Vnom; VchCode))
      Str = Str & Str2 & CR
      Count = Count + 1
    endwhile
    ShowMessage(Str)
  endif

В итоге получим результат как в предыдущей части материала:

 

При формировании запроса вручную, очень помогает утилита трассировки SOAP-вызовов, в которой видно, какой запрос мы отправляем сервису и какой ответ от него получаем.

Это пожалуй все, что я хотел рассказать об использовании WEB-сервисов в DIRECTUM. Еще раз повторюсь, что более подробную информацию, включая примеры, можно получить из справки Microsoft SOAP Toolkit 3.0.

14
Авторизуйтесь, чтобы оценить материал.
1
Андрей Посаженников

Добавлю несколько моментов относительно аутентификации с которыми сталкивался:

  1. Аутентификация будет работать только для безопасности на уровне транспорта, а не на уровне сообщения (насколько мне помнится, WS-Security MSSOAP не поддерживает).
  2. Windows аутентификация подхватывается MSSOAP без каких бы то ни было настроек со стороны клиента, что очень удобно, но работает только в рамках домена.
  3. Для обычных xml сервисов в принципе не возникнет проблем парсинга WSDL описания, но для более сложных могут возникнуть проблемы. Насколько я помню MSSOAP не поддерживает такие разделы WSDL как policy и import. От раздела import в принципе можно избавиться, если сделать flat файл WSDL, то есть запихнуть все данные, которые располагаются по указанному URL в один файлик.
Mikhail Kislitsyn

Андрей.
3. На моей практике MSSOAP3.0 без проблем подтягивает imports которые генерит WCF. На худой случай можно поставить .NET4.5 и flat вариант будет предоставлен автоматически 

По-моему и 1 и 2 разруливаются настройками ConnectorProperty.

Неизвестный пользователь:
"Client:Incorrect number of parameters supplied for SOAP request" - количество переданных параметров не соответствует описанию метода. Вероятно указаны не все параметры, которые принимает метод. 

 

Дмитрий Тарасов
Аутентификация будет работать только для безопасности на уровне транспорта, а не на уровне сообщения (насколько мне помнится, WS-Security MSSOAP не поддерживает).

Только что получилось передать пакет из DIRECTUM веб-сервису, с использованием WS-Security, путем формирования пакета вручную с помощью "MSSOAP.SoapReader30".

Дмитрий Тарасов

Опечатался и поправить никак :(

Сформировать пакет вручную можно с помощью "MSSOAP.SoapSerializer30"

Константин Егоров

сталкивался с проблемой, что WSDL файл находиться под защитой логина и пароля, тогда выпадает ошибка

WSDLReader:XML Parser failed at linenumber 0, lineposition 0, reason is: The download of the specified resource has failed.
HRESULT=0x1: Incorrect function.
- WSDLReader:Loading of the WSDL file failed HRESULT=0x80070057: The parameter is incorrect.
- Client:One of the parameters supplied is invalid. HRESULT=0x80070057: The parameter is incorrect

Тогда нам требуется прописать URL-строку к WSDL файлу с логином и паролем по транскрипции (далее пример):

https://LOGIN:PASS@mywebservice:9052/sdv/ErpHub/1.0?wsdl

Где LOGIN - логин, PASS - пароль

Константин Егоров: обновлено 18.03.2021 в 10:22

Авторизуйтесь, чтобы написать комментарий