wsdl2objc: несоответствие ContractFilter в EndpointDispatcher
У нас есть служба.NET WCF, которая общается с приложением для iPhone. Я использую wsdl2objc для генерации кода objc, необходимого для всей магии SOAP. SoapUI может добавить wsdl этого сервиса и правильно отправлять запросы. Но запрос, сгенерированный wsdl2objc, жалуется на это:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Sender</s:Value>
<s:Subcode>
<s:Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="en-US">The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
</s:Text>
</s:Reason>
</s:Fault>
</s:Body>
</s:Envelope>
Однако, если я использую то же самое s:Envelope
с SoapUI запрос работает правильно. Насколько я могу видеть, единственное различие между двумя запросами заключается в разделе заголовка, где wsdl2objc генерирует это:
SOAPAction:http://xx/AuthenticateDevice
но мыло генерирует:
Content-Type: application/soap+xml;charset=UTF-8;action="http://xx/AuthenticateDevice"
Я попытался изменить код, сгенерированный wsdl2objc, и заменил это:
[request setValue:soapAction forHTTPHeaderField:@"SOAPAction"];
NSString *contentType = [NSString stringWithFormat:@"application/soap+xml; charset=utf-8;"];
[request setValue:contentType forHTTPHeaderField:@"Content-Type"];
с этим:
[request setValue:soapAction forHTTPHeaderField:@"action"];
NSString *contentType = [NSString stringWithFormat:@"application/soap+xml; charset=utf-8;"];
[request setValue:contentType forHTTPHeaderField:@"Content-Type"];
Но я только что получил ошибку 400 сейчас. Любая помощь высоко ценится!
Спасибо,
Тея.
3 ответа
У меня была похожая проблема, которая была исправлена путем изменения URL схемы конверта в выводе wsdl2objc
Я изменил это
xmlNsPtr soapEnvelopeNs = xmlNewNs(root, (const xmlChar*)"http://www.w3.org/2003/05/soap-envelope", (const xmlChar*)"soap");
к этому:
xmlNsPtr soapEnvelopeNs = xmlNewNs(root, (const xmlChar*)"http://schemas.xmlsoap.org/soap/envelope/", (const xmlChar*)"soap");
и это, казалось, исправило мои вызовы веб-службы WCF от iOS.
Я думаю, это означает, что моя версия wsdl2objc выводит конверт SOAP 1.1, когда серверу WCF, кажется, требуется SOAP 1.2.
Кто-нибудь еще заметил это? Есть ли другой способ настроить это, а не изменить после генерации кода?
В службах WCF, с которыми я работал, я только что передал значение "text/xml"
в Content-Type
заголовок, а затем передал правильное значение действия мыла в отдельном SOAPAction
заголовок (аналогично тому, как это делал wsdl2objc).
Вот пара вещей, чтобы проверить:
- Ваша служба WCF использует basicHttpBinding или что-то еще. (Кажется, я помню, что читал, что привязки, кроме basicHttpBinding, не работают (или вообще) с iOS - но я не уверен)
- Каково правильное значение действия SOAP для этой службы? В сервисах, с которыми я работаю, он построен с использованием
<ServiceNamespace>\<WCFInterfaceName>\<MethodName>
Похоже, что мне не хватало начальных кавычек и конечных кавычек вокруг значения действия, которое вызывало это. Вот код, который работал для меня, но я не доволен настройкой action
как часть http content-type
заголовок. Так что, если кто-то может предложить лучшее решение, я был бы рад отдать должное:
NSString *contentType = [NSString stringWithFormat:@"application/soap+xml; charset=utf-8; action=\"%@\"", soapAction];
[request setValue:contentType forHTTPHeaderField:@"Content-Type"];