Это еще не все.
В стандартах есть некоторая неопределенность, которая может вызвать проблемы совместимости. Вы должны использовать тип или элемент в зависимости от того, используете ли вы службу на основе документов или службу на основе RPC.
Есть и неясности. Если вы скажете
<wsdl:message name="message1" type="ns:type1"/>
Затем вы сказали, что содержимое сообщения должно проверяться на соответствие типу ns:type1. Но вы ничего не сказали об элементе, содержащем контент. В каком пространстве имен он будет находиться?
Обратитесь к базовому профилю WS-I для получения некоторых правил по этому .
В комментариях обсуждались варианты 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>
Обратите внимание, что слово wrap не появляется. То, что 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>
person
John Saunders
schedule
23.07.2009