从.NET使用Cisco WSMA(第二部分)
首先,快速浏览一下我的其他问题(第1部分 ).它说明了我如何使用WCF从.NET 4在Cisco路由器(Web服务管理代理-WSMA)上调用Web服务.
First, take a quick look at my other question (part 1). It tells of how I want to call web services on a Cisco router (The Web Services Management Agent - WSMA) from .NET 4 using WCF.
我已经应用了拉迪斯拉夫的技术,并且走得很远.但是,我现在处于一个阶段,在这个阶段中,我非常有信心自己正在发送格式正确的SOAP请求,但是路由器不接受它.
I have applied Ladislav's technique, and gotten very far. However, I'm now at a stage where I'm pretty confident that I'm sending well-formed SOAP requests, yet the router does not accept it.
在Cisco 文档,有几个有效的SOAP请求示例,例如:
In the Cisco documentation, there are several examples of valid SOAP requests, such as this one:
<?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跟踪,我验证所发送的请求如下所示:
Using WCF trace, I verify that the request I'm sending looks like this:
<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命名空间是在soap主体上而不是在信封上声明的,但这应该没有区别.失败时动作属性是可选的,并在其他示例中提供. xs:type也应该可以.否则,它是完全等效的.还是?
To me, that looks pretty damn right. Yes, the xsd and xsi namespaces are declared on the soap body rather than the envelope, but that should make no difference. The action-on-fail attribute is optional, and present in other examples. The xs:type should be OK too. Otherwise, it's completely equivalent. Or?
仍然,我总是得到的响应是:
Still, the response I invariably get is:
<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>
我看不到任何元素丢失.
I can't see that any element is missing.
您不认为IOS要求名称空间前缀为SOAP(而不是s)吗?那将是完全愚蠢的,但是我用尽了所有的选项(谁知道,也许他们不对XML进行反序列化,而是对它们进行文本解析).有谁知道我如何指定WCF用于SOAP信封的名称空间前缀?
You don't suppose IOS requires the namespace prefix to be SOAP (rather than s)? That would be utterly stupid, but I'm running out of options (who knows, maybe they don't deserialize the XML, but rather parses it textually). Does anyone know how I can specify the namespace prefix that WCF will use for the SOAP envelope?
是的.
通过在路由器上使用WCF跟踪,提琴手和调试,以及通过HTTP手动发布消息,我终于弄清楚了发生了什么.
Using WCF tracing, fiddler and debugging on the router, and manually posting messages over HTTP, I have finally figured out what's going on.
结果证明,路由器上的WSMA代理期望HTTP请求中的SOAP消息有效载荷包含XML声明.而且WCF没有发送.
Turns out the WSMA agent on the router expects the SOAP message payload in the HTTP request to include an XML declaration. And WCF isn't sending one.
我发布了新问题关于如何使WCF客户端通过其SOAP请求发送XML声明.
I have posted a new question about how to make the WCF client send an XML declaration with its SOAP requests.