Не удается сформулировать объект ответа для SOAP Node.js

Я пишу веб-сервис SOAP Node.js, используя node-soap, и не могу понять как правильно сформулировать ответ.

Я интегрирую веб-приложение с QuickBooks 2013 с помощью веб-коннектора. Клиент сделает запрос на аутентификацию, и я могу зарегистрировать переданные аргументы, поэтому я знаю, что он вызывается, но я не могу получить правильный ответ.

В документации говорится, что в качестве ответа ожидается массив строк. Соответствующие части WSDL выглядят так:

  <s:element name="authenticateResponse">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="authenticateResult" type="tns:ArrayOfString" />
      </s:sequence>
    </s:complexType>
  </s:element>

  <s:complexType name="ArrayOfString">
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
    </s:sequence>
  </s:complexType>

 <wsdl:message name="authenticateSoapOut">
    <wsdl:part name="parameters" element="tns:authenticateResponse" />
</wsdl:message>

<wsdl:operation name="authenticate">
  <wsdl:input message="tns:authenticateSoapIn" />
  <wsdl:output message="tns:authenticateSoapOut" />
</wsdl:operation>

 <wsdl:operation name="authenticate">
  <soap:operation soapAction="http://developer.intuit.com/authenticate" style="document" />
  <wsdl:input>
    <soap:body use="literal" />
  </wsdl:input>
  <wsdl:output>
    <soap:body use="literal" />
  </wsdl:output>
</wsdl:operation>

Я испробовал множество различных способов настройки объекта ответа, но клиент продолжает получать сообщения об ошибках (QuickBooks Web Connector)

У меня есть JavaScript:

    var myService = {
          'QBWebConnectorSvc': {
              'QBWebConnectorSvcSoap': {
                  authenticate: function(args) {

                           //i have tried many variations of nesting arrays/objects etc.
                    var toReturn = {
                        "ArrayOfString":[guid()," "," "," "]
                    };
                    return toReturn;
                  }
              }
          }
      }

     var xml = require('fs').readFileSync('qbwc.wsdl', 'utf8'),
          server = http.createServer(function(request,response) {
              response.end("404: Not Found: "+request.url)
          });

    server.listen(8000);

    soap.listen(server, '/wsdl', myService, xml);

Каким-то образом мне нужно построить «ArrayOfString», но я понятия не имею, как это сделать; Я новичок во всем, что касается мыла.


person thermite    schedule 21.12.2013    source источник
comment
Какие ошибки вы получаете?   -  person JohnB    schedule 24.02.2014
comment
@JohnB Я на самом деле не помню, я решил использовать php-фреймворк keithpalmers и просто сделать конечную точку отправки, которую я вызываю из узла, и оба приложения общаются с одной и той же базой данных.   -  person thermite    schedule 25.02.2014
comment
оглядываясь назад, он никогда не будет аутентифицироваться   -  person thermite    schedule 25.02.2014
comment
Вам, вероятно, это уже не интересно, но для всех, кто наткнулся на это: QBWC не нравится ответ XML, который node-soap создает для массивов. Я подтвердил это, перехватив динамически созданный ответ и вместо этого жестко запрограммировав его быть. Я работаю над тем, чтобы лучше понять, как node-soap создает XML, чтобы я мог изменить его, чтобы отправить то, что ожидает QBWC. Я обязательно опубликую ответ здесь, когда он заработает.   -  person JohnB    schedule 25.02.2014
comment
Я только что провел последнюю неделю, борясь со стратегией пространства имен node-soap, я полностью переписал синтаксический анализатор WSDL с нуля, чтобы разобраться с ним. Но я не пишу сервер, я не знаю, та ли это проблема, с которой вы сталкиваетесь, но это кажется вероятным. Способ, которым node-soap преобразует литерал объекта в XML, довольно прост, а пространство имен — нет.   -  person Jason    schedule 26.02.2014
comment
@ Джейсон, спасибо за ваш вклад. Это действительно была проблема с пространством имен, с ней разобрались без необходимости каким-либо образом изменять функцию node-soap objectToXML (к счастью!)   -  person JohnB    schedule 26.02.2014
comment
Функция objectToXML не позволяет назначить пространство имен любому элементу, вложенному ниже первого дочернего элемента элемента body, а также не позволяет вам установить более одного пространства имен для этого первого дочернего элемента. Это было критическим ограничением в моем приложении, но, похоже, оно не для QuickBooks.   -  person Jason    schedule 26.02.2014


Ответы (1)


Краткий ответ:

Ваша функция аутентификации должна выглядеть так:

authenticate: function(args) {
    return {
        authenticateResult: { string: [guid(), {}] }
    };
}

Объяснение:

В вашем коде есть пара ошибок, я опубликую сообщения об ошибках для каждого, чтобы сделать их более доступными для поиска для тех, у кого возникнет такая же проблема в будущем.

QBWC1012: Ссылка на объект не указывает на экземпляр объекта.

Вы должны возвращать authenticateResult внутри объекта, а не ArrayOfString.

QBWC1012: Аутентификация не удалась из-за следующего сообщения об ошибке. Индекс находился вне границ массива.

QBWC не нравится XML-ответ, который node-soap создает для массивов. Вот (соответствующая часть), что производит node-soap, если вы возвращаете массив внутри объекта (т.е. return { authenticateResult: [guid(), ""] }:

<tns:authenticateResponse xmlns:tns="http://developer.intuit.com/" xmlns="http://developer.intuit.com/">
    <tns:authenticateResult>bdaa63cf-2d26-4d6b-8a54-6f519af6e8d4</tns:authenticateResult>
</tns:authenticateResponse>

А вот что ожидает QBWC:

<tns:authenticateResponse xmlns:tns="http://developer.intuit.com/" xmlns="http://developer.intuit.com/">
    <tns:authenticateResult>
        <tns:string>bdaa63cf-2d26-4d6b-8a54-6f519af6e8d4</tns:string>
        <tns:string></tns:string>
    </tns:authenticateResult>
</tns:authenticateResponse>

Первая проблема заключается в неправильном пространстве имен. Второй — node-soap пропускает пустую строку и не включает ее в ответ, но QBWC ищет ее (отсюда индекс выходит за границы). Хакерское решение, которое я опубликовал, решит обе эти проблемы:

  • Добавление массива с ключом string в объект authenticateResult исправит пространство имен.
  • Пустой объект вместо пустой строки не будет пропущен синтаксическим анализатором objectToXML node-soap.
person JohnB    schedule 25.02.2014
comment
Этот ответ только что сэкономил мне часы разочарования, спасибо! Ожидайте крупную награду в ближайшее время. :-) - person Shadow Wizard Wearing Mask V2; 24.07.2016
comment
Наслаждайтесь своей репутацией, вы ее заслужили! :-) - person Shadow Wizard Wearing Mask V2; 25.07.2016