web-dev-qa-db-fra.com

Quelle est la différence entre le type et l'élément dans WSDL?

Dans un fichier WSDL, une fonction peut renvoyer un type ou un élément. Jusqu'à présent, je n'ai utilisé que des types personnalisés. Cependant, je me demande quand l'élément devrait être plus approprié que le type. Quelle est la différence entre eux?

Y a-t-il une différence entre

<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" element="tns:Person"></wsdl:part>
</wsdl:message>

et

<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" type="tns:Person"></wsdl:part>
</wsdl:message>

du point de vue du client (application utilisant le service Web)?

Comme Skaffman l'a souligné, la question ci-dessus mène à une autre question. Quelle est la différence entre

<xs:element name="Person" ... >
 ...
</xs:element>

et

<xs:complexType name="Person">
   ...
</xs:complexType>

?

42
czuk

Il y a plus que ça.

Il existe une certaine ambiguïté dans les normes qui peut causer des problèmes d’interopérabilité. Vous devez utiliser le type ou l'élément selon que vous utilisez un service basé sur le document ou un service basé sur le RPC.

Il y a aussi des ambiguïtés. Si tu le dis

<wsdl:message name="message1" type="ns:type1"/>

Ensuite, vous avez dit que le contenu du message doit être validé contre le type "ns: type1". Mais vous n'avez rien dit sur l'élément qui contient le contenu. Dans quel espace de noms sera-t-il?

Reportez-vous au Profil de base WS-I pour connaître les règles à ce sujet.


Il y a eu quelques discussions dans les commentaires à propos de "document/literal" vs. "document/literal/wrapped". Voici ma prise.

Je viens de créer un service Web. Voici le tout:

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;
        }
    }
}

Je ne posterai pas le WSDL entier, mais voici les "bonnes parties":

<?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>

Notez que le mot "enveloppé" n'apparaît pas. Ce que IBM appelle dans leur document "document/literal/wrapped", c'est simplement "document/literal", qui utilise une seule partie de message, dont le nom est dérivé du nom du service et qui se réfère à à un élément, et qui contient à la fois les paramètres de l'opération.

Il n'y a rien de magique ici, il n'y a rien de non standard ici. 

Dans de nombreuses organisations de normalisation, les entreprises finissent par prendre parti. Dans le cas de SOAP, nous avons le "côté RPC" et le "côté Document". RPC est plus familier à beaucoup de gens - il mappe un à un avec un appel de fonction. Le document est moins familier et nécessite que vous pensiez réellement en termes de XML simple. IBM était peut-être du côté RPC, je ne sais pas.


J'ai maintenant terminé le document IBM, Quel style de WSDL. Le résumé est:

Résumé

Il existe quatre styles de reliure (il y en a réellement cinq, mais document/encoded n'a pas de sens). Bien que chaque style ait sa place, dans la plupart des situations, le meilleur style est celui qui est recouvert de document/littéral.


Je souhaite également réagir aux endroits du document où il est expliqué le niveau de difficulté de la répartition, en fonction de la présence ou non du nom de l'opération dans le message. C'est un faux problème. Si vous lisez le document, vous remarquerez qu'il ne traite jamais de rien dans la section <binding>. La solution au problème "pas de nom d'opération" est là.

<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 est envoyé dans les en-têtes HTTP de la demande et peut être utilisé pour la distribution:

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>
16
John Saunders

Celui que vous utilisez dépend du schéma auquel il fait référence. Si tns: Person est défini dans le schéma comme suit:

<xs:element name="Person" ... >
 ...
</xs:element>

Ensuite, vous utilisez 

<wsdl:part name="parameters" element="tns:Person">

Si, par contre, le schéma est défini comme 

<xs:complexType name="Person">
   ...
</xs:complexType>

alors vous utilisez 

<wsdl:part name="parameters" type="tns:Person">

La question est donc de savoir quelle est la différence entre les éléments de schéma et les types de schéma. 

10
skaffman

Je ne peux pas commenter la partie WSDL de la question, mais je vais répondre à la partie XML Schema.

<xs:complexType> définit un type, qui décrit contenu d’un élément, sans décrire l’élément lui-même (c’est-à-dire son nom). <xs:element> décrit un élément (en particulier son nom), mais pas son type. Cependant, <xs:element> toujours references le type du contenu de l’élément qu’il décrit. Cela peut être une référence à un type existant (y compris, mais sans s'y limiter, <xs:complexType> - il peut également s'agir de <xs:simpleType>, par exemple) définition ailleurs dans le schéma, ou d'une définition inline <xs:complexType>:

<xs:element name="foo">
   <xs:complexType>
      ...
   </xs:complexType>
</xs:element>

Étant donné que la construction ci-dessus est si courante, vous pouvez en fait omettre entièrement <xs:complexType>, ce qui sera implicite. 

Quant à savoir si vous devez toujours définir les types séparément, puis les référencer dans les déclarations d'éléments, ou si vous préférez définir des types d'éléments en ligne dans les déclarations d'éléments, c'est une question de style. 

2
Pavel Minaev
<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>

l'attribut <element> de type fait référence à l'attribut <complexType> de name.


<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" element="tns:person"></wsdl:part>
</wsdl:message>

et

<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" type="tns:person"></wsdl:part>
</wsdl:message>
  • Le paramètre <part> est associé à un type concret défini dans l'élément conteneur <types>. et <part> peut faire référence à l'attribut <complexType> by type ou à l'attribut <element> by element, comme indiqué ci-dessus.
  • Il peut s'agir de <complexType> ou <portType> ou de l'un quelconque, référencés par l'attribut type.
0
Premraj