In WSDL file a function can return a Type or an Element. I have used only custom types as a results so far. However, I wonder when the Element should be more appropriate than the Type? What is the difference between them?
在WSDL文件中,函数可以返回Type或Element。到目前为止,我只使用自定义类型作为结果。但是,我想知道什么时候Element应该比Type更合适?他们之间有什么区别?
Is there any difference between
两者之间有什么区别吗?
<wsdl:message name="MyFunction">
<wsdl:part name="parameters" element="tns:Person"></wsdl:part>
</wsdl:message>
and
<wsdl:message name="MyFunction">
<wsdl:part name="parameters" type="tns:Person"></wsdl:part>
</wsdl:message>
from a Client perspective (application that uses the web service)?
从客户角度(使用Web服务的应用程序)?
The above question, as skaffman pointed, leads to a another question. What is the difference between
正如斯卡弗曼指出的那样,上述问题引出了另一个问题。有什么区别
<xs:element name="Person" ... >
...
</xs:element>
and
<xs:complexType name="Person">
...
</xs:complexType>
?
4 个解决方案
#1
There's more to it than that.
除此之外还有更多。
There is some ambiguity in the standards that can cause interoperability problems. You have to use type or element depending on whether you're using a Document-based service or an RPC-based service.
标准中存在一些可能导致互操作性问题的模糊性。您必须使用类型或元素,具体取决于您使用的是基于文档的服务还是基于RPC的服务。
There are also ambiguities. If you say
也有歧义。如果你说
<wsdl:message name="message1" type="ns:type1"/>
Then you've said that the content of the message must validate against type "ns:type1". But you've said nothing about the element that contains the content. What namespace will it be in?
然后你说过消息的内容必须根据类型“ns:type1”进行验证。但是你对包含内容的元素一无所知。它的名称空间是什么?
Refer to the WS-I Basic Profile for some rules on this.
有关此问题的一些规则,请参阅WS-I Basic Profile。
There's been some discussion in the comments about "document/literal" vs. "document/literal/wrapped". Here's my take.
关于“document / literal”与“document / literal / wrapped”的评论中有一些讨论。这是我的看法。
I just created a web service. Here's the whole thing:
我刚刚创建了一个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;
}
}
}
I won't post the entire WSDL, but here are the "good parts":
我不会发布整个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>
Note how the word "wrapped" does not appear. What IBM in their document is calling "document/literal/wrapped" is simply "document/literal", that happens to use a single message part, that happens to have a name derived from the name of the service, and that happens to refer to an element, and which happens to contain both the parameters to the operation.
请注意“包裹”一词是如何显示的。 IBM在他们的文档中调用“document / literal / wrapped”只是“document / literal”,碰巧使用单个消息部分,恰好有一个名称派生自服务名称,而且恰好引用到一个元素,它碰巧包含操作的参数。
There's nothing magical here, there's nothing non standard here.
这里没什么神奇的,这里没有什么不标准的。
In many standards organizations companies wind up taking sides. In the case of SOAP, we've got the "RPC side" and the "Document side". RPC is more familiar to many people - it maps one to one with a function call. Document is less familiar, and requires that you actually think in terms of simple XML. Perhaps IBM was on the RPC side, I don't know.
在许多标准组织中,公司最终会站在一边。在SOAP的情况下,我们有“RPC方面”和“文档方面”。 RPC对许多人来说比较熟悉 - 它通过函数调用一对一映射。文档不太熟悉,并且要求您实际考虑简单的XML。也许IBM在RPC方面,我不知道。
I have now finished the IBM document, Which style of WSDL. The summary is:
我现在已经完成了IBM文档,哪种WSDL样式。摘要是:
Summary
There are four binding styles (there are really five, but document/encoded is meaningless). While each style has its place, under most situations the best style is document/literal wrapped.
有四种绑定样式(实际上有五种,但文档/编码没有意义)。虽然每种风格都有它的位置,但在大多数情况下,最好的风格是文档/文字包装。
I also want to react to the places in the document where it discusses the level of difficulty in dispatching, based on whether the operation name is present in the message. This is a non-issue. If you read the document, you'll note that it never discusses anything in the <binding>
section. The solution to the "no operation name" problem is there.
我还想根据消息中是否存在操作名称,对文档中讨论调度难度的地方作出反应。这不是问题。如果您阅读该文档,您会注意到它从未讨论
<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"/>
The soapAction is sent in the HTTP headers of the request, and can be used for dispatching:
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>
#2
Which one you use depends on the schema to which it is referring. If tns:Person is defined in the schema as:
您使用哪一个取决于它所引用的架构。如果tns:Person在模式中定义为:
<xs:element name="Person" ... >
...
</xs:element>
Then you use
然后你用
<wsdl:part name="parameters" element="tns:Person">
If, on the other hand, the schema is defined as
另一方面,如果将模式定义为
<xs:complexType name="Person">
...
</xs:complexType>
then you use
然后你用
<wsdl:part name="parameters" type="tns:Person">
So the question is really what's the difference between Schema elements, and Schema types.
所以问题实际上是Schema元素和Schema类型之间的区别。
#3
I cannot comment on the WSDL part of the question, but I'll answer the XML Schema part.
我无法评论问题的WSDL部分,但我将回答XML Schema部分。
<xs:complexType>
defines a type, which describes content of an element, without describing the element itself (i.e. its name). <xs:element>
describes an element (specifically its name), but not its type. However, <xs:element>
always references the type for the content of the element it describes. This can be a reference to an existing type (including, but not limited to, <xs:complexType>
- it can also be <xs:simpleType>
, for example) definition elsewhere in the schema, or an inline <xs:complexType>
definition:
<xs:element name="foo">
<xs:complexType>
...
</xs:complexType>
</xs:element>
Since the above construct is so common, you can actually omit <xs:complexType>
entirely, and it will be implied.
由于上面的构造很常见,实际上你可以完全省略
As for whether you should always define types separately and then reference them in element declarations, or whether you should prefer defining element types inline within element declarations, it is a matter of style.
至于你是否应该总是单独定义类型然后在元素声明中引用它们,或者你是否应该更喜欢在元素声明中内联定义元素类型,这是一个风格问题。
#4
<xs:element name="person" type="persontype"/>
<xs:complexType name="persontype">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
the <element>
of type
attribute is referring <complexType>
of name
attribute.
type属性的
<wsdl:message name="MyFunction">
<wsdl:part name="parameters" element="tns:person"></wsdl:part>
</wsdl:message>
and
<wsdl:message name="MyFunction">
<wsdl:part name="parameters" type="tns:person"></wsdl:part>
</wsdl:message>
-
<part>
parameter associates with a concrete type defined in the<types>
container element. and<part>
can refer to either<complexType>
bytype
attribute or<element>
by element attribute as shown above. - It can be either
<complexType>
or<portType>
or any, which are referred bytype
attribute.
它可以是
#1
There's more to it than that.
除此之外还有更多。
There is some ambiguity in the standards that can cause interoperability problems. You have to use type or element depending on whether you're using a Document-based service or an RPC-based service.
标准中存在一些可能导致互操作性问题的模糊性。您必须使用类型或元素,具体取决于您使用的是基于文档的服务还是基于RPC的服务。
There are also ambiguities. If you say
也有歧义。如果你说
<wsdl:message name="message1" type="ns:type1"/>
Then you've said that the content of the message must validate against type "ns:type1". But you've said nothing about the element that contains the content. What namespace will it be in?
然后你说过消息的内容必须根据类型“ns:type1”进行验证。但是你对包含内容的元素一无所知。它的名称空间是什么?
Refer to the WS-I Basic Profile for some rules on this.
有关此问题的一些规则,请参阅WS-I Basic Profile。
There's been some discussion in the comments about "document/literal" vs. "document/literal/wrapped". Here's my take.
关于“document / literal”与“document / literal / wrapped”的评论中有一些讨论。这是我的看法。
I just created a web service. Here's the whole thing:
我刚刚创建了一个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;
}
}
}
I won't post the entire WSDL, but here are the "good parts":
我不会发布整个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>
Note how the word "wrapped" does not appear. What IBM in their document is calling "document/literal/wrapped" is simply "document/literal", that happens to use a single message part, that happens to have a name derived from the name of the service, and that happens to refer to an element, and which happens to contain both the parameters to the operation.
请注意“包裹”一词是如何显示的。 IBM在他们的文档中调用“document / literal / wrapped”只是“document / literal”,碰巧使用单个消息部分,恰好有一个名称派生自服务名称,而且恰好引用到一个元素,它碰巧包含操作的参数。
There's nothing magical here, there's nothing non standard here.
这里没什么神奇的,这里没有什么不标准的。
In many standards organizations companies wind up taking sides. In the case of SOAP, we've got the "RPC side" and the "Document side". RPC is more familiar to many people - it maps one to one with a function call. Document is less familiar, and requires that you actually think in terms of simple XML. Perhaps IBM was on the RPC side, I don't know.
在许多标准组织中,公司最终会站在一边。在SOAP的情况下,我们有“RPC方面”和“文档方面”。 RPC对许多人来说比较熟悉 - 它通过函数调用一对一映射。文档不太熟悉,并且要求您实际考虑简单的XML。也许IBM在RPC方面,我不知道。
I have now finished the IBM document, Which style of WSDL. The summary is:
我现在已经完成了IBM文档,哪种WSDL样式。摘要是:
Summary
There are four binding styles (there are really five, but document/encoded is meaningless). While each style has its place, under most situations the best style is document/literal wrapped.
有四种绑定样式(实际上有五种,但文档/编码没有意义)。虽然每种风格都有它的位置,但在大多数情况下,最好的风格是文档/文字包装。
I also want to react to the places in the document where it discusses the level of difficulty in dispatching, based on whether the operation name is present in the message. This is a non-issue. If you read the document, you'll note that it never discusses anything in the <binding>
section. The solution to the "no operation name" problem is there.
我还想根据消息中是否存在操作名称,对文档中讨论调度难度的地方作出反应。这不是问题。如果您阅读该文档,您会注意到它从未讨论
<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"/>
The soapAction is sent in the HTTP headers of the request, and can be used for dispatching:
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>
#2
Which one you use depends on the schema to which it is referring. If tns:Person is defined in the schema as:
您使用哪一个取决于它所引用的架构。如果tns:Person在模式中定义为:
<xs:element name="Person" ... >
...
</xs:element>
Then you use
然后你用
<wsdl:part name="parameters" element="tns:Person">
If, on the other hand, the schema is defined as
另一方面,如果将模式定义为
<xs:complexType name="Person">
...
</xs:complexType>
then you use
然后你用
<wsdl:part name="parameters" type="tns:Person">
So the question is really what's the difference between Schema elements, and Schema types.
所以问题实际上是Schema元素和Schema类型之间的区别。
#3
I cannot comment on the WSDL part of the question, but I'll answer the XML Schema part.
我无法评论问题的WSDL部分,但我将回答XML Schema部分。
<xs:complexType>
defines a type, which describes content of an element, without describing the element itself (i.e. its name). <xs:element>
describes an element (specifically its name), but not its type. However, <xs:element>
always references the type for the content of the element it describes. This can be a reference to an existing type (including, but not limited to, <xs:complexType>
- it can also be <xs:simpleType>
, for example) definition elsewhere in the schema, or an inline <xs:complexType>
definition:
<xs:element name="foo">
<xs:complexType>
...
</xs:complexType>
</xs:element>
Since the above construct is so common, you can actually omit <xs:complexType>
entirely, and it will be implied.
由于上面的构造很常见,实际上你可以完全省略
As for whether you should always define types separately and then reference them in element declarations, or whether you should prefer defining element types inline within element declarations, it is a matter of style.
至于你是否应该总是单独定义类型然后在元素声明中引用它们,或者你是否应该更喜欢在元素声明中内联定义元素类型,这是一个风格问题。
#4
<xs:element name="person" type="persontype"/>
<xs:complexType name="persontype">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
the <element>
of type
attribute is referring <complexType>
of name
attribute.
type属性的
<wsdl:message name="MyFunction">
<wsdl:part name="parameters" element="tns:person"></wsdl:part>
</wsdl:message>
and
<wsdl:message name="MyFunction">
<wsdl:part name="parameters" type="tns:person"></wsdl:part>
</wsdl:message>
-
<part>
parameter associates with a concrete type defined in the<types>
container element. and<part>
can refer to either<complexType>
bytype
attribute or<element>
by element attribute as shown above. - It can be either
<complexType>
or<portType>
or any, which are referred bytype
attribute.
它可以是