Я заранее извиняюсь, если этот пост слишком длинный. Но 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. Я бы опубликовал ссылку, но, видимо, мне не хватает репутации.