Неправильная обработка прокси-сервера WCF вернула конверт SOAP

У меня есть веб-сервис PHP с кодировкой RPC, который возвращает простой мыльный конверт с логическим типом данных. При выполнении трассировки на стороне клиента мыльный конверт выглядит следующим образом прямо перед тем, как попасть в прокси-сервер WCF:

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns1="http://sample.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org
/soap/encoding/">
  <SOAP-ENV:Body>
    <ns1:ServiceMessageResponse>
       <outgoingVar1>true</outgoingVar1>
    </ns1:ServiceMessageResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Однако, когда возвращаемое значение выходит с другой стороны прокси, оно было изменено на false. Я пробовал добавить xsi: type = "xsd: boolean" к outgoingVar1, но это не помогает. Сам по себе мыльный конверт - это именно то, чего следует ожидать клиенту, но по какой-то причине он его не использует правильно. Это связано с тем, как настроена веб-служба PHP, или это связано с прокси-сервером WCF? Веб-сервис PHP просто настраивается следующим образом:

ini_set('soap.wsdl_cache_enabled', '0');
ini_set('soap.wsdl_cache_ttl', '0');
$soapServer = new SoapServer('wsdl/sample.wsdl', array('soap_version' => SOAP_1_1));
$soapServer->addFunction('Service');
$soapServer->handle();

и функция заканчивается простым "return true"; линия. Здесь ничего сложного. Есть идеи, в чем может быть проблема?

Аннотированный WSDL (удаленные тривиальные пространства имен и измененные настоящие) выглядит так:

<wsdl:definitions name="IJLSoapResponse" targetNamespace="http://casey.com"
tns="http://casey.com" xmlns:samp="http://sample.com" ...>
  <wsdl:types>
    <xsd:schema targetNamespace="http://casey.com" ...>
            <xsd:element name="incomingVar1" type="xsd:string" nillable="true"/>
            <xsd:element name="incomingVar2" type="xsd:string" nillable="true"/>
    </xsd:schema>
    <xsd:schema targetNamespace="http://sample.com" ...>
            <xsd:element name="outgoingVar1" type="xsd:boolean" nillable="true"/>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="ServiceInput">
    <wsdl:part name="incomingVar1" element="tns:incomingVar1"/>
    <wsdl:part name="incomingVar2" element="tns:incomingVar2"/>
  </wsdl:message>
  <wsdl:message name="ServiceOutput">
    <wsdl:part name="outgoingVar1" element="samp:outgoingVar1"/>
  </wsdl:message>
  <wsdl:portType name="ServicePortType">
    <wsdl:operation name="ServiceMessage" parameterOrder="incomingVar1 incomingVar2">
            <wsdl:input name="ServiceMessageRequest" message="tns:ServiceInput"/>
            <wsdl:output name="ServiceMessageResponse" message="tns:ServiceOutput"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="ServiceBinding" type="tns:ServicePortType">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="ServiceMessage">
            <soap:operation soapAction="http://casey.com/soap/Service"/>
            <wsdl:input name="ServiceMessageRequest">
                    <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://casey.com"/>
            </wsdl:input>
            <wsdl:output name="ServiceMessageResponse">
                    <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://sample.com"/>
            </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="ServiceService">
    <wsdl:port name="ServicePort" binding="tns:ServiceBinding">
            <soap:address location="http://casey.com/soap/Service"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Этого должно быть достаточно, чтобы увидеть, как вещи объявляются ... дайте мне знать, если вам нужно что-то еще пояснить. Спасибо за вашу помощь!


person Casey Crites    schedule 15.07.2009    source источник
comment
Каков ваш контракт со стороны WCF?   -  person tomasr    schedule 16.07.2009
comment
@caseycrites: мне нужно было бы увидеть часть кода WCF, чтобы соединить здесь 2 и 2. Я передам это нескольким другим людям, которые могут.   -  person RSolberg    schedule 16.07.2009
comment
Контракт WCF - это код партнера, поэтому я не думаю, что смогу его достать ... или опубликовать здесь. Прости...   -  person Casey Crites    schedule 16.07.2009
comment
Рекомендация по размещению WSDL. Не удаляйте тривиальные пространства имен - это означает, что мне нужно добавить их обратно, чтобы использовать. Не помещайте ... или что-нибудь еще, что является недопустимым XML. Если вы хотите что-то подобное, используйте комментарий.   -  person John Saunders    schedule 16.07.2009
comment
Вы что-нибудь узнали об этом?   -  person John Saunders    schedule 30.08.2009


Ответы (2)


Можем ли мы увидеть WSDL службы? Мне интересно, в каком пространстве имен должен находиться outgoingVar1.

Службы с кодировкой RPC всегда были проблемой из-за неоднозначности того, в каких частях сообщения пространства имен должны находиться. Я не удивлюсь, увидев, что это проблема.


Следующая привязка, похоже, работает в soapUI. По крайней мере, он может генерировать фиктивный сервис, а ответное сообщение выглядит так, как вы искали (outgoingVar1 в образце пространства имен):

<wsdl:binding name="ServiceBinding" type="tns:ServicePortType">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="ServiceMessage">
        <soap:operation soapAction="http://casey.com/soap/Service"/>
        <wsdl:input name="ServiceMessageRequest">
            <soap:body parts="incomingVar1 incomingVar2" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://casey.com"/>
        </wsdl:input>
        <wsdl:output name="ServiceMessageResponse">
            <soap:body parts="outgoingVar1" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://sample.com"/>
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>
person John Saunders    schedule 16.07.2009
comment
outgoingVar1 должен быть частью sample.com ... в мыльной оболочке не должно быть ns1 (sample.com) распространяется на потомков ServiceResponse? - person Casey Crites; 16.07.2009
comment
Нет. Пространства имен так не распространяются. Для этого потребовалось бы xmlns = sample.com (в дальнейшем сделайте sample.com пространством имен по умолчанию) . Ns1 применяется только к тому элементу, в котором он используется. - person John Saunders; 16.07.2009
comment
Я немного поигрался с WSDL с XMLSpy и с soapUI. soapUI это не нравится. Кажется, что имена ввода и вывода должны совпадать между portType и привязкой. - person John Saunders; 16.07.2009
comment
Джон: Спасибо за вашу помощь, и с этого момента я буду следить и сохранять пространства имен. Несоответствие WSDL было ошибкой редактирования, которую я исправил выше. Я добавил атрибут parts к узлу soap: body, но это никак не повлияло на внешний вид выходного конверта SOAP. Он по-прежнему без префикса. - person Casey Crites; 16.07.2009
comment
Когда я создаю фиктивный сервис в soapUI, я получаю outgoingVar1 как часть правильного пространства имен. Однако, когда я попадаю в реальную службу с тем же WSDL, он возвращается только с ServiceMessageResponse с префиксом. Что-то не хватает в декларации самой службы PHP? - person Casey Crites; 16.07.2009
comment
Извините, я не думаю, что когда-либо даже видел PHP, пока вы не разместите его выше. Я могу только предположить, что он по-разному интерпретирует WSDL, что является проблемой для служб RPC. Кстати, вы можете проверить службу на соответствие WS-I. Я не знаю, как заставить это работать в soapUI. - person John Saunders; 16.07.2009

В итоге решение касалось пространств имен. Поскольку они не распространялись правильно, мне нужно было добавить в схему атрибут elementFormDefault = "квалифицированный". Это заставляет префикс присутствовать в каждом элементе, и это единственный способ сделать .NET счастливым. Спасибо за вашу помощь в этом.

person Casey Crites    schedule 09.09.2009