Подтвердить что ты не робот

В чем разница между типом и элементом в WSDL?

В WSDL файле функция может возвращать Тип или Элемент. До сих пор я использовал только настраиваемые типы. Однако, интересно, когда Элемент должен быть более подходящим, чем Тип? В чем разница между ними?

Есть ли разница между

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

и

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

с точки зрения клиента (приложение, использующее веб-службу)?

Этот вопрос, как указал скаффман, приводит к другому вопросу. В чем разница между

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

и

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

?

4b9b3361

Ответ 1

Там больше, чем это.

В стандартах существует некоторая двусмысленность, которая может вызвать проблемы совместимости. Вы должны использовать тип или элемент в зависимости от того, используете ли вы службу на основе документов или службу на основе RPC.

Есть также двусмысленности. Если вы скажете

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

Затем вы сказали, что содержимое сообщения должно проверяться против типа "ns: type1". Но вы ничего не сказали об элементе, который содержит контент. В каком пространстве имен оно будет находиться?

Обратитесь к WS-I Basic Profile для некоторых правил.


В комментариях "document/literal" было высказано некоторое обсуждение по сравнению с "document/literal/wrapped". Вот мой прием.

Я только что создал веб-сервис. Здесь все:

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>

Обратите внимание, что слово "завернутый" не отображается. То, что IBM в своем документе вызывает "document/literal/wrapped", - это просто "документ/литерал", который использует одну часть сообщения, которая имеет имя, полученное от имени службы, и это происходит со ссылкой к элементу и который, как оказалось, содержит оба параметра для операции.

Здесь нет ничего волшебного, здесь нет ничего стандартного.

Во многих компаниях, входящих в стандарты, компании начинают принимать участие. В случае SOAP у нас есть "сторона RPC" и "сторона документа". RPC более знаком многим людям - он сопоставляет один к одному с вызовом функции. Документ менее знаком и требует, чтобы вы на самом деле думали в терминах простого XML. Возможно, IBM была на стороне RPC, я не знаю.


Теперь я закончил документ IBM, какой стиль WSDL. Резюме:

Резюме

Существует четыре стиля привязки (их действительно пять, но document/encoded не имеет смысла). В то время как каждый стиль имеет свое место, в большинстве ситуаций лучший стиль обернут документом/литералом.


Я также хочу реагировать на места в документе, где он обсуждает уровень сложности при отправке, исходя из того, присутствует ли в сообщении имя операции. Это не проблема. Если вы прочитаете документ, вы заметите, что он никогда ничего не обсуждает в разделе <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>

Ответ 2

Какой из них вы используете, зависит от схемы, к которой он относится. Если tns: Person определено в схеме как:

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

Затем вы используете

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

Если, с другой стороны, схема определена как

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

то вы используете

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

Итак, вопрос в том, какова разница между элементами схемы и типами схем.

Ответ 3

Я не могу прокомментировать часть WSDL вопроса, но я отвечу на часть XML-схемы.

<xs:complexType> определяет тип, который описывает содержимое элемента, без описания самого элемента (то есть его имени). <xs:element> описывает элемент (в частности его имя), но не его тип. Однако <xs:element> всегда ссылается на тип содержимого описываемого элемента. Это может быть ссылка на существующий тип (включая, но не ограничиваясь этим, <xs:complexType> - это также может быть <xs:simpleType>, например) определение в другом месте схемы или встроенное определение <xs:complexType>:

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

Так как приведенная выше конструкция настолько распространена, вы можете полностью опустить <xs:complexType>, и это будет подразумеваться.

Что касается того, следует ли всегда определять типы по отдельности, а затем ссылаться на них в объявлениях элементов или следует ли вам определять типы элементов внутри строки в объявлениях элементов, это вопрос стиля.

Ответ 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>

<element> атрибута type ссылается на <complexType> атрибута name.


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

и

<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" type="tns:person"></wsdl:part>
</wsdl:message>
  • Параметр
  • <part> ассоциируется с конкретным типом, определенным в элементе контейнера <types>. и <part> может ссылаться на атрибут <complexType> на type или <element> на атрибут элемента, как показано выше.
  • Это может быть либо <complexType>, либо <portType>, либо любое, которое относится к атрибуту type.