Работа с Cisco WSMA из.NET (часть вторая)
Во-первых, взгляните на другой мой вопрос ( часть 1). В нем рассказывается о том, как я хочу вызывать веб-службы на маршрутизаторе Cisco (агент управления веб-службами - WSMA) из.NET 4 с использованием WCF.
Я применил технику Ладислава и получил очень далеко. Однако сейчас я нахожусь на этапе, когда я довольно уверен, что отправляю правильно сформированные SOAP-запросы, но маршрутизатор его не принимает.
В документации Cisco есть несколько примеров допустимых запросов SOAP, таких как этот:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP:Body>
<request xmlns="urn:cisco:wsma-config" correlator="4.1">
<configApply details="all">
<config-data>
<cli-config-data>
<cmd>no cns config partial mixy</cmd>
<cmd>no stupid</cmd>
<cmd>no cns exec 80 </cmd>
</cli-config-data>
</config-data>
</configApply>
</request>
</SOAP:Body>
</SOAP:Envelope>]]>]]>
Используя трассировку WCF, я проверяю, что отправляемый запрос выглядит так:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<request correlator="1" xmlns="urn:cisco:wsma-config">
<configApply action-on-fail="rollback" details="all">
<config-data>
<cli-config-data>
<cmd xsi:type="xsd:string">hostname Gunnar</cmd>
</cli-config-data>
</config-data>
</configApply>
</request>
</s:Body>
</s:Envelope>
Для меня это выглядит чертовски верно. Да, пространства имен xsd и xsi объявляются в теле мыла, а не в конверте, но это не должно иметь значения. Атрибут action-on-fail является необязательным и присутствует в других примерах. Тип xs: тоже должен быть в порядке. В противном случае, это полностью эквивалентно. Или же?
Тем не менее, ответ, который я всегда получаю, таков:
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xml="http://www.w3.org/XML/1998/namespace">
<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"></s:Header>
<SOAP:Body>
<SOAP:Fault>
<faultcode xmlns="">SOAP:Client</faultcode>
<faultstring xmlns="">An expected XML tag or sequence is missing</faultstring>
<detail xmlns="">
<WSMA-ERR:error xmlns:WSMA-ERR="urn:cisco:wsma-errors">
<WSMA-ERR:tag>xml</WSMA-ERR:tag>
<WSMA-ERR:details>XML_ERROR_MISSING_ELEMENT</WSMA-ERR:details>
</WSMA-ERR:error>
</detail>
</SOAP:Fault>
</SOAP:Body>
</SOAP:Envelope>
Я не вижу, что какой-то элемент отсутствует.
Вы не думаете, что IOS требует, чтобы префикс пространства имен был SOAP (а не s)? Это было бы совершенно глупо, но у меня заканчиваются варианты (кто знает, может быть, они не десериализуют XML, а анализируют его текстово). Кто-нибудь знает, как я могу указать префикс пространства имен, который WCF будет использовать для конверта SOAP?
1 ответ
Ага.
Используя трассировку WCF, fiddler и отладку на маршрутизаторе, а также отправляя сообщения вручную по HTTP, я наконец выяснил, что происходит.
Оказывается, агент WSMA на маршрутизаторе ожидает, что полезная нагрузка сообщения SOAP в запросе HTTP будет включать декларацию XML. И WCF не отправляет.
Я опубликовал новый вопрос о том, как заставить клиента WCF отправлять декларацию XML со своими запросами SOAP.