假设我说WSDL定义了一个接受复杂类型的操作,这是非常常见的webmethod之类的东西:
<xs:element name="createBill">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="customer" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="billId" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<wsdl:message name="createBillRequest">
<wsdl:part name="parameters" element="ns:createBill" />
</wsdl:message>
<wsdl:operation name="creatBill">
<wsdl:input wsaw:Action="urn:createBill" message="axis2:createBillRequest" />
...
</wsdl:operation>
两个不同调用的WebServices标准实现规则是什么,一个指定billId为xsi:nil
,另一个完全省略节点?
<creatBill ...>
<customer>1332400</customer>
<billId xsi:nil="true"/>
</createBill>
vs
<creatBill ...>
<customer>1332400</customer>
</createBill>
为了揭示更多背景,我遇到了一个Java家伙的问题。他的网络服务是在Axis2中完成的(由于我不熟悉的原因)处理bill元素的遗漏与nil值不同。我的主张是它们是同一个,并且在两种情况下都应该表现相同(例如创建动态billID)。他的主张是它不一样,他只在缺少节点时生成动态ID,否则在节点被填充时返回错误(“billId missing”)。
我对他的主张的实际问题是,.NET中的WCF和WS堆栈都将它们视为同一个,甚至没有规定省略nillable参数,这使得我几乎不可能实现客户端没有编写我自己的WS-stack,以及他实现的WS-Security。目前我只能调用指定null的服务:
serv.createBill("1332400", null);
serv.createBill("1332400"); // ERROR: no such method
我甚至不了解他是如何在Java中实现服务器端的,因此一个Web方法具有不同的调用模式,当省略节点时,Axis2设置的billID参数是什么?他非常不合作,我需要一些论据(如果有的话)提交给他和后来的经理,因为他们是在支持合同下。
既然我们不能都是对的,有谁知道WS标准在这里规定了什么?谁是标准的错?我没有开始使用wcf vs axis flame(请注意),我需要从SOAP / WSDL标准和规范的角度看待这个问题作为两者的父级。
答案 0 :(得分:3)
您的Web服务使用文档/文字样式。在这种情况下,Web服务规范只要求XML Schema元素声明描述消息内容(更具体地说是SOAP主体的单个子节点),当然它也符合该声明。现在,XML Schema确实允许同时使用minOccurs =“0”和nillable =“true”,但规范没有附加任何特定含义的元素缺失与xsi:nil =“true的元素“;特别是它没有声明这两种情况是等价的。由模式的设计者来定义这两种情况的含义。
另请注意,没有通用标准描述如何将WSDL和模式转换为特定于语言的结构。
话虽如此,minOccurs =“0”和nillable =“true”在一起是有问题的,因为大多数语言只有一个概念,即空值,表示没有值。虽然如果使用minOccurs =“0”或nillable =“true”声明元素,使用null值效果很好,但是没有自然的方法来处理用两者声明的元素。 JAX-WS规范解决了此问题,如以下问题所述:
Jaxb generated class used JAXBElement instead of specified type
与JAX-WS相反,其他一些特定于语言的Web服务绑定约定无法正确解决此问题,并且将minOccurs =“0”与nillable =“true”一起使用通常会导致互操作性问题。因此,这应该被认为是一种不好的做法,但遗憾的是,Web服务规范中没有任何条款禁止这样做。
答案 1 :(得分:0)
无法确定Axis服务是否符合可以为空的值的某些WS标准,但您可以通过设置EmitDefaultValue setting of the DataMember attribute来调整WCF客户端生成的代码。如果将其设置为false,则当可空类型的值为null时,WCF将不会创建相应的XML元素,这似乎是服务正在查找的内容。