这不仅仅只是如此。
标准中存在一些模糊不清的地方会导致互操作性问题。根据您使用基于文档的服务还是基于RPC的服务,您必须使用类型或元素。
还有一些歧义。如果您说
<wsdl:message name="message1" type="ns:type1"/>
你说过消息的内容必须符合类型“ns:type1”的验证。但是你没有提到包含内容的元素。它将在什么命名空间中?
请参考WS-I基本配置文件了解一些规则。
在评论中有关于“文档/面向对象”与“文档/面向对象/包装”的讨论。这是我的看法。
我刚刚创建了一个 Web 服务。以下是整个内容:
using System.Web.Services;
namespace WebService1
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class SimpleMathService : WebService
{
[WebMethod]
public int Add(int a, int b)
{
return a + b;
}
[WebMethod]
public int Multiply(int a, int b)
{
return a*b;
}
}
}
我不会发布整个 WSDL,但这里是“好的部分”:
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://tempuri.org/" xmlns:tns="http://tempuri.org/" >
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:element name="Add">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="a" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="b" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="AddResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1"
name="AddResult" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="int" type="s:int"/>
</s:schema>
</wsdl:types>
<wsdl:message name="AddSoapIn">
<wsdl:part name="parameters" element="tns:Add"/>
</wsdl:message>
<wsdl:message name="AddSoapOut">
<wsdl:part name="parameters" element="tns:AddResponse"/>
</wsdl:message>
<wsdl:portType name="SimpleMathServiceSoap">
<wsdl:operation name="Add">
<wsdl:input message="tns:AddSoapIn"/>
<wsdl:output message="tns:AddSoapOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SimpleMathServiceSoap" type="tns:SimpleMathServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="Add">
<soap:operation soapAction="http://tempuri.org/Add" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SimpleMathService">
<wsdl:port name="SimpleMathServiceSoap" binding="tns:SimpleMathServiceSoap">
<soap:address location="http://localhost:5305/SimpleMathService.asmx"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
注意单词“wrapped”未出现。IBM在其文档中所称的“document/literal/wrapped”实际上指的是“document/literal”,它恰好使用单个消息部分,该部分名称来自服务名称的派生名称,引用一个元素,并且包含操作的参数。
这里没有什么神奇的,也没有什么非标准的东西。
在许多标准组织中,公司会站在不同的立场上。对于SOAP而言,我们有“RPC方面”和“文档方面”。RPC对许多人来说更为熟悉-它将一对一地映射到函数调用。文档则较不熟悉,并要求您实际上以简单的XML格式思考。也许IBM站在了RPC方面,我不知道。
我现在已经完成了IBM文档,具体内容是关于哪种WSDL样式。总结如下:
总结
有四种绑定样式(实际上有五种,但document/encoded无意义)。虽然每种样式都有其用途,但在大多数情况下,最好的样式是document/literal wrapped。
我还想回应文档中讨论基于消息是否存在操作名称而难度分配的地方。这不是问题。如果你阅读文档,你会发现它从未讨论过<binding>
部分的任何内容。“没有操作名称”问题的解决方案在那里。
<wsdl:binding name="SimpleMathServiceSoap" type="tns:SimpleMathServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="Add">
<soap:operation soapAction="http://tempuri.org/Add" style="document"/>
soapAction 是发送在请求的 HTTP 头中的,可用于消息分发:
POST /SimpleMathService.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/Add"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Add xmlns="http://tempuri.org/">
<a>int</a>
<b>int</b>
</Add>
</soap:Body>
</soap:Envelope>