2013-02-23 3 views
1

Я заранее извиняюсь, если этот пост слишком длинный. Но 1) это мой первый пост и 2) Я действительно был над рекой и через лес, пытаясь понять это.API-интерфейс BACBox SOAP getClient - вызов не выполняется с использованием инфраструктуры клиента WCF

Функция добавления служебной ссылки в Visual Studio 2012 создает прокси-сервер, который (по-видимому) генерирует недопустимые сообщения SOAP. Я подозреваю, что это связано с сериализацией или тем, как оформляются типы прокси, но я не могу понять это. Помощь очень ценится.

Детали 1. Моей среда Visual Studio 2012 и я создал библиотеку классов приложения .NET 4.5 с ссылкой на службу к https://sandbox-api.bancbox.com/v1/BBXPort?wsdl. Я пытаюсь вызвать функцию getClient(); который определен здесь. (http://www.bancbox.com/api/view/45)

код выглядит следующим образом:

public void GetClient() 

{ 
    // create an instance of the service reference proxy class 
    var bbx=newBBXClient(); 
    bbx.ChannelFactory.Endpoint.Behaviors.Remove<System.ServiceModel.Description.ClientCredentials>(); 
    bbx.ChannelFactory.Endpoint.Behaviors.Add(new CustomCredentials()); 

    bbx.ClientCredentials.UserName.UserName="MY_USERNAME"; 
    bbx.ClientCredentials.UserName.Password="MY_PASSWORD"; 

    var customerId=newid { 
      subscriberReferenceId="44XX33YY" 
    }; 

    var request=newgetClientRequest { 
      subscriberId=MY_SUBSCRIBER_ID, 
      clientId=customerId 
    }; 

    var response=bbx.getClient(request); 
} 

Деталь 2. я сделал много успешных вызовов в веб-службу через SoapUI. Успешные SoapUI-произведенные сообщения SOAP выглядеть следующим образом

<soapenv:Envelope xmlns:sch="schema.bancbox.com" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
<soapenv:Header> 
    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
     <wsse:UsernameToken wsu:Id="UsernameToken-11"> 
      <wsse:Username>MY_USERNAME</wsse:Username> 
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">MY_PASSWORD</wsse:Password> 
      <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">tRLo6AlRKl+/rULiKq6A6g==</wsse:Nonce> 
      <wsu:Created>2013-02-22T18:32:02.204Z</wsu:Created> 
     </wsse:UsernameToken> 
    </wsse:Security> 
</soapenv:Header> 
<soapenv:Body> 
    <sch:getClient> 
     <getClientRequest> 
      <subscriberId>MY_SUBSCRIBER_ID</subscriberId> 
       <clientId> 
        <!--Optional:--> 
        <subscriberReferenceId>44XX33YY</subscriberReferenceId> 
       </clientId> 
     </getClientRequest> 
    </sch:getClient> 
</soapenv:Body> 
</soapenv:Envelope> 

Деталь 3. Per Скрипач, мои неудачные сообщения SOAP выглядеть следующим образом

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
<s:Header> 
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPozcAgEH0QhJHloqMBWUf3mAAAAAA5wy3enJkDUGU8IaMUCFyEjzfL+1Uez1HhAvEeFpJ+30ACQAA</VsDebuggerCausalityData> 
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
     <o:UsernameToken u:Id="uuid-6e1c9f81-0651-41f7-b659-26b191bf7e13-1" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
      <o:Username>MY_USERNAME</o:Username> 
      <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">MY_PASSWORD</o:Password> 
      <o:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">hGggJkxurSkHQ3MKoeBK6AmEHNs=</o:Nonce> 
      <u:Created>2013-02-23T11:24:47.663Z</u:Created> 
     </o:UsernameToken> 
    </o:Security> 
</s:Header> 
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <getClient xmlns="schema.bancbox.com"> 
     <getClientRequest xmlns=""> 
      <subscriberId>MY_SUBSCRIBER_ID</subscriberId> 
      <clientId> 
       <subscriberReferenceId>XX55YY22</subscriberReferenceId> 
      </clientId> 
     </getClientRequest> 
    </getClient> 
</s:Body> 
</s:Envelope> 

Сообщение SOAP выше производится при выполнении GetClient (). GetClient выбрасывает следующее исключение.

System.ServiceModel.FaultException 
Unmarshalling Error: cvc-elt.4.2: Cannot resolve 'getClientRequest' to a type definition for element 'getClientRequest'. 

Когда я повторю то же самое сообщение неудовлетворительного используя SoapUI, я получаю следующий ответ:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
<soap:Body> 
    <soap:Fault> 
     <faultcode>soap:Client</faultcode> 
     <faultstring>Unmarshalling Error: cvc-elt.4.2: Cannot resolve 'getClientRequest' to a type definition for element 'getClientRequest'. </faultstring> 
    </soap:Fault> 
</soap:Body> 
</soap:Envelope> 

Детали 4. На основании своих исследований, это указует на то, что сервер, на другом конце Apache CXS. Это задыхается от моего запроса SOAP. Поэтому я начал играть с моим сообщением SOAP и отправил его через SoapUI.

Первое вопиющее расстояние в успешном сообщении, и мой провал сообщений этих строки

УСПЕХ

<sch:getClient> 
    <getClientRequest> 

FAIL

<getClient xmlns="schema.bancbox.com"> 
    <getClientRequest xmlns=""> 

Итак, первое, что я сделал, чтобы мой getClientRequest тег идентичен успешному.

<getClient xmlns="schema.bancbox.com"> 
    <getClientRequest> 

Это произвело следующий ответ.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
<soap:Body> 
    <soap:Fault> 
     <faultcode>soap:Server</faultcode> 
     <faultstring>Found element {schema.bancbox.com}getClientRequest but could not find matching RPC/Literal part</faultstring> 
    </soap:Fault> 
</soap:Body> 
</soap:Envelope> 

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

ПЕРЕД

<getClient xmlns="schema.bancbox.com"> 

ПОСЛЕ

<s:Envelope xmlns:bb="schema.bancbox.com" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
. . . 
    <bb:getClient> 
     <getClientRequest> 
. . . 
    </bb:getClient> 

Сообщение результирующая SOAP выглядит следующим образом, и это успешно.

<s:Envelope xmlns:bb="schema.bancbox.com" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
<s:Header> 
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPozcAgEH0QhJHloqMBWUf3mAAAAAA5wy3enJkDUGU8IaMUCFyEjzfL+1Uez1HhAvEeFpJ+30ACQAA</VsDebuggerCausalityData> 
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
     <o:UsernameToken u:Id="uuid-6e1c9f81-0651-41f7-b659-26b191bf7e13-1" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
      <o:Username>MY_USERNAME</o:Username> 
      <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">MY_PASSWORD</o:Password> 
      <o:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">hGggJkxurSkHQ3MKoeBK6AmEHNs=</o:Nonce> 
      <u:Created>2013-02-23T11:24:47.663Z</u:Created> 
     </o:UsernameToken> 
    </o:Security> 
</s:Header> 
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <bb:getClient> 
     <getClientRequest> 
      <subscriberId>MY_SUBSCRIBER_ID</subscriberId> 
      <clientId> 
       <subscriberReferenceId>XX55YY22</subscriberReferenceId> 
      </clientId> 
     </getClientRequest> 
    </bb:getClient> 
</s:Body> 
</s:Envelope> 

Таким образом, вопросы о миллионе долларов - ПОЧЕМУ и КАК.

* ПОЧЕМУ класс .NET proxy сериализует SOAP-сообщение так, как он это делает?

* КАК его исправить? Как я могу включить прокси-сервер в сообщение SOAP выше? Как заставить сериализатор определять сокращенное пространство имен сообщений в Envelop и затем использовать сокращенное обозначение тега сообщения?

FYI, чтобы даже добраться до этого момента, мне пришлось преодолеть ряд проблем WCF WSE и в конечном итоге реализовало решение, столь щедро предоставленное в блоге Rich Stahls. Я бы опубликовал ссылку, но, видимо, мне не хватает репутации.

ответ

0

Насколько я понимаю, SOAP-сообщение, которое производит WCF, является синтаксически правильным. Однако веб-службы Java CXF очень жесткие в отношении сообщений SOAP, которые они будут принимать.

Решение настройки псевдонимов для определения пространства имен XML в операции узел SOAP-сообщений, полученных с помощью WCF прокси конкретной проблемы подразумевает осуществление пользовательских сообщений Инспектор подробно здесь: Force WCF to create an xml namespace alias in client proxy.

Это полностью решило мою проблему.