WSDL- und Serviceverträge
Das hilfsprogramm Wsutil.exe generiert einen C-Sprach-Stub gemäß den bereitgestellten WSDL-Metadaten sowie Datentypdefinitionen und Beschreibungen für Datentypen, die von vom Benutzer erstellten XML-Schemas beschrieben werden.
Im Folgenden finden Sie ein Beispiel für ein WSDL-Dokument- und XML-Schema, das als Grundlage für die folgende Diskussion dient:
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://Example.org"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" targetNamespace="http://Example.org"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xs:schema xmlns:tns="http://Example.org" elementFormDefault="qualified"
targetNamespace="http://Example.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="SimpleMethod">
<xs:complexType>
<xs:sequence>
<xs:element name="a" type="xs:int" />
<xs:element name="b" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SimpleMethodResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="b" type="xs:int" />
<xs:element name="c" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="ISimpleService_SimpleMethod_InputMessage">
<wsdl:part name="parameters" element="tns:SimpleMethod" />
</wsdl:message>
<wsdl:message name="ISimpleService_SimpleMethod_OutputMessage">
<wsdl:part name="parameters" element="tns:SimpleMethodResponse" />
</wsdl:message>
<wsdl:portType name="ISimpleService">
<wsdl:operation name="SimpleMethod">
<wsdl:input wsaw:Action="http://Example.org/ISimpleService/SimpleMethod"
message="tns:ISimpleService_SimpleMethod_InputMessage" />
<wsdl:output wsaw:Action="http://Example.org/ISimpleService/SimpleMethodResponse"
message="tns:ISimpleService_SimpleMethod_OutputMessage" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DefaultBinding_ISimpleService" type="tns:ISimpleService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="SimpleMethod">
<soap:operation soapAction="http://Example.org/ISimpleService/SimpleMethod"
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="SimpleService">
<wsdl:port name="ISimpleService" binding="tns:DefaultBinding_ISimpleService">
<soap:address location="http://Example.org/ISimpleService" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
In diesem Beispiel wird ein Vertrag, ISimpleService, mit einer einzigen Methode, SimpleMethod, bereitgestellt. "SimpleMethod" verfügt über zwei Eingabeparameter vom Typ ganze Zahl, ein und b, die vom Client an den Dienst gesendet werden. Ebenso verfügt SimpleMethod über zwei Ausgabeparameter vom Typ integer, b und c, die nach erfolgreichem Abschluss an den Client zurückgegeben werden. In sal-annotated C syntax, the method definition appears as follows:
void SimpleMethod(__in int a, __inout int * b, __out int * c );
In dieser Definition ist ISimpleService ein Dienstvertrag mit einem einzelnen Dienstvorgang: SimpleMethod.
Die Ausgabeheaderdatei enthält Definitionen und Beschreibungen für externe Verweise. Dazu gehören:
- C-Strukturdefinitionen für globale Elementtypen.
- Ein Vorgangsprototyp, der in der aktuellen Datei definiert ist.
- Ein Funktionstabellenprototyp für die in der WSDL-Datei angegebenen Verträge.
- Clientproxy- und Dienst-Stubprototypen für alle in der aktuellen Datei angegebenen Funktionen.
- Eine WS_ELEMENT_DESCRIPTION Datenstruktur für die globalen Schemaelemente, die in der aktuellen Datei definiert sind.
- Eine WS_MESSAGE_DESCRIPTION Datenstruktur für alle nachrichten, die in der aktuellen Datei angegeben sind.
- Eine WS_CONTRACT_DESCRIPTION Datenstruktur für alle in der aktuellen Datei angegebenen Verträge.
Eine globale Struktur wird generiert, um alle globalen Beschreibungen für die Schematypen und Dienstmodelltypen zu kapseln, auf die die Anwendung verweisen kann. Die Struktur wird mit einem normalisierten Dateinamen benannt. In diesem Beispiel generiert Wsutil.exe eine globale Definitionsstruktur namens "example_wsdl", die alle Webdienstbeschreibungen enthält. Die Strukturdefinition wird in der Stubdatei generiert.
typedef struct _example_wsdl
{
struct {
WS_ELEMENT_DESCRIPTION SimpleMethod;
WS_ELEMENT_DESCRIPTION SimpleMethodResponse;
} elements;
struct {
WS_MESSAGE_DESCRIPTION ISimpleService_SimpleMethod_InputMessage;
WS_MESSAGE_DESCRIPTION ISimpleService_SimpleMethod_OutputMessage;
} messages;
struct {
WS_CONTRACT_DESCRIPTION DefaultBinding_ISimpleService;
} contracts;
} _example_wsdl;
extern const _stockquote_wsdl stockquote_wsdl;
Für globale Elementdefinitionen im XML-Schemadokument (XSD) werden ein WS_ELEMENT_DESCRIPTION Prototyp sowie die entsprechende C-Typdefinition für jedes element generiert. Die Prototypen für die Elementbeschreibungen für SimpleMethod und SimpleMethodResponse werden als Member in der obigen Struktur generiert. Die C-Strukturen werden wie folgt generiert:
typedef struct SimpleMethod
{
int a;
int b;
} SimpleMethod;
typedef struct SimpleMethodResponse
{
int b;
int c;
} SimpleMethodResponse;
Ähnlich wie bei globalen komplexen Typen generiert Wsutil.exe Typ C-Strukturdefinitionen wie oben, ohne übereinstimmende Elementbeschreibungen.
Für WSDL-Eingaben generiert Wsutil.exe die folgenden Prototypen und Definitionen:
- Für die Nachrichtenbeschreibung wird ein WS_MESSAGE_DESCRIPTION Prototyp generiert. Diese Beschreibung kann sowohl vom Dienstmodell als auch von der Nachrichtenebene verwendet werden. Nachrichtenbeschreibungsstrukturen sind Felder namens "Messagename" in der globalen Struktur. In diesem Beispiel wird die Nachrichtenbeschreibung als ISimpleService_SimpleMethod_InputMessage Feld in der ISimpleService_SimpleMethod_InputMessage Struktur generiert, wie in der WSDL-Datei angegeben.
- WS_CONTRACT_DESCRIPTION Prototyp wird für die Vertragsbeschreibung generiert. Diese Beschreibung wird vom Dienstmodell verwendet. Vertragsbeschreibungsstrukturen sind Felder namens "Contractname" in der globalen Struktur. In diesem Beispiel wird die Vertragsbeschreibung als DefaultBinding_ISimpleService Feld in der Struktur "_example_wsdl" generiert.
Vorgangs- und Typspezifikationen gelten sowohl für Proxy als auch für Stub und werden in beiden Dateien generiert. Wsutil.exe generiert nur eine Kopie, wenn sowohl der Proxy als auch der Stub in derselben Datei generiert werden.
Generierung von Bezeichnern
Die oben aufgeführten automatisch generierten C-Strukturen werden basierend auf dem in der WSDL-Datei angegebenen Namen erstellt. Ein XML-NCName wird häufig nicht als gültiger C-Bezeichner betrachtet, und die Namen werden nach Bedarf normalisiert. Hexwerte werden nicht konvertiert, und allgemeine Buchstaben wie ":", "/" und "." werden in den Unterstrich "_" konvertiert, um die Lesbarkeit zu verbessern.
Kopfzeile für den Stub
Für jeden Vorgang im Dienstvertrag wird eine Rückrufroutine mit dem Namen "<Operationname>Callback" generiert. (Beispielsweise hat der Vorgang "SimpleMethod" im Beispieldienstvertrag einen generierten Rückruf namens "SimpleMethodCallback".)
typedef HRESULT (CALLBACK *SimpleMethodCallback) (
const WS_OPERATION_CONTEXT * context,
int a, int *b, int *c,
const WS_ASYNC_CONTEXT *asyncContext,
WS_ERROR * error);
Für jede WSDL portType generiert Wsutil.exe eine Funktionstabelle, die portTypedarstellt. Jeder Vorgang auf dem portType weist einen entsprechenden Funktionszeiger auf den Rückruf auf, der in der Funktionstabelle vorhanden ist.
struct ISimpleServiceMethodTable
{
ISimpleService_SimpleMethodCallback SimpleMethod;
};
Proxyprototypen werden für alle Vorgänge generiert. Der Prototypname ist der Vorgangsname (in diesem Fall "SimpleMethod"), der in der WSDL-Datei für den Dienstvertrag angegeben ist.
HRESULT WINAPI SimpleMethod(WS_CHANNEL *channel,
WS_HEAP *heap,
int a,
int *b,
int *c,
const WS_ASYNC_CONTEXT * asyncContext,
WS_ERROR * error );
Prototypgenerierung mit nur lokaler Beschreibung
Die Proxy- undStub-Dateien enthalten die Definition für die globale Definitionsstruktur, einschließlich Prototypen und Definitionen für die Strukturen, die nur lokale Beschreibungen und Clientproxy-/Dienst-Stubimplementierungen enthalten.
Alle Prototypen und Definitionen, die lokal für die Stubdatei sind, werden als Teil einer gekapselten Struktur generiert. Diese übergeordnete lokale Beschreibungsstruktur bietet eine klare Hierarchie der Beschreibungen, die von der Serialisierungsebene und dem Dienstmodell benötigt werden. Die lokale Beschreibungsstruktur weist Prototypen auf, die dem unten gezeigten ähneln:
struct _filenameLocalDefinitions
{
struct {
// schema related output for all the embedded
// descriptions that needs to describe global complex types.
} globalTypes;
// global elements.
struct {
// schema related output, like field description
// structure description, element description etc.
...
} globalElements;
struct {
// messages and related descriptions
} messages;
struct {
// contract and related descriptions.
} contracts;
struct {
// XML dictionary entries.
} dictionary;
} _filenameLocalDefinitions;
Verweisen auf Definitionen aus anderen Dateien
Lokale Definitionen können auf Beschreibungen verweisen, die in einer anderen Datei generiert wurden. Beispielsweise kann die Nachricht in der aus der WSDL-Datei generierten C-Codedatei definiert werden, aber das Nachrichtenelement kann an anderer Stelle in der aus der XSD-Datei generierten C-Codedatei definiert werden. In diesem Fall generiert Wsutil.exe einen Verweis auf das globale Element aus der Datei, die die Nachrichtendefinition enthält, wie unten dargestellt:
{ // WS_MESSAGE_DESCRIPTION
...
(WS_ELEMENT_DESRIPTION *)b_xsd.globalElement.<elementname>
};
Beschreibungen des globalen Elements
Für jedes globale Element, das in einer wsdl:type- oder XSD-Datei definiert ist, gibt es ein übereinstimmende Feld mit dem Namen ElementName innerhalb des GlobalElement--Felds. In diesem Beispiel wird eine Struktur mit dem Namen "SimpleMethod" generiert:
typedef struct _SimpleServiceLocal
{
struct // global elements
{
struct // SimpleMethod
{
...
WS_ELEMENT_DESCRIPTION SimpleMethod;
} SimpleMethod;
...
} globalElements;
}
Andere Beschreibungen, die von der Elementbeschreibung benötigt werden, werden als Teil der enthaltenden Struktur generiert. Wenn das Element ein einfaches Typelement ist, gibt es nur ein WS_ELEMENT_DESCRIPTION Feld. Wenn der Elementtyp eine Struktur ist, werden alle verwandten Felder und Strukturbeschreibungen als Teil der Elementstruktur generiert. In diesem Beispiel ist das SimpleMethod-Element eine Struktur mit zwei Feldern, einer und b. Wsutil.exe generiert die Struktur wie folgt:
...
struct // SimpleMethod
{
struct // SimpleMethod structure
{
WS_FIELD_DESCRIPTION a;
WS_FIELD_DESCRIPTION b;
WS_FIELD_DESCRIPTION * SimpleMethodFields [2];
WS_STRUCT_DESCRIPTION structDesc;
} SimpleMethoddescs; // SimpleMethod
WS_ELEMENT_DESCRIPTION elementDesc;
} SimpleMethod;
...
Eingebettete Strukturen und eingebettete Elemente werden nach Bedarf als Unterstrukturen generiert.
WSDL-verwandte Definitionen
Wsutil.exe generiert ein Feld unter dem WSDL-Abschnitt für jeden der portType- Werte, die unter dem angegebenen wsdl:service definiert sind.
...
struct { // WSDL
struct { // portTypeName
struct { // operationName
} operationName;
...
WS_OPERATION_DESCRIPTION* operations[numOperations];
WS_CONTRACT_DESCRIPTION contractDesc;
} portTypeName;
}
...
Wsutil.exe generiert ein Feld f, das alle beschreibungen enthält, die für den Vorgang erforderlich sind, ein Signlearray von Zeigern auf jede der Vorgangsbeschreibungen für jede Methode und eine WS_CONTRACT_DESCRIPTION für die angegebene portType.
Alle Beschreibungen, die von Vorgängen benötigt werden, werden innerhalb des felds operationName unter dem angegebenen portType-generiert. Dazu gehören das WS_ELEMENT_DESCRIPTION-Feld sowie die Unterstruktur für Eingabe- und Ausgabeparameter. Ebenso werden die WS_MESSAGE_DESCRIPTION Felder für die Eingabenachricht und die optionale Ausgabenachricht zusammen mit der; WS_PARAMETER_DESCRIPTION Listenfeld für alle Vorgangsparameter und das WS_OPERATION_DESCRIPTION Feld für den Vorgang selbst. In diesem Beispiel wird die Codestruktur für die SimpleMethod-Beschreibung wie unten dargestellt generiert:
...
struct // messages
{
WS_MESSAGE_DESCRIPTION ISimpleService_SimpleMethod_InputMessage;
WS_MESSAGE_DESCRIPTION ISimpleService_SimpleMethod_OutputMessage;
} messages;
struct // contracts
{
struct // DefaultBinding_ISimpleService
{
struct // SimpleMethod
{
WS_PARAMETER_DESCRIPTION params[3];
WS_OPERATION_DESCRIPTION SimpleMethod;
} SimpleMethod;
WS_OPERATION_DESCRIPTION* operations[1];
WS_CONTRACT_DESCRIPTION contractDesc;
} DefaultBinding_ISimpleService;
} contracts;
...
VERWANDTE XML-Wörterbuchdefinitionen
Namen und Namespaces, die in verschiedenen Beschreibungen verwendet werden, werden als Felder vom Typ WS_XML_STRINGgeneriert. Alle diese Zeichenfolgen werden als Teil eines Dateikonstantenwörterbuchs generiert. Die Liste der Zeichenfolgen und des felds WS_XML_DICTIONARY (namens diktieren im folgenden Beispiel) werden als Teil des Wörterbuchfelds der fileNameLocal Struktur generiert.
struct { // fileNameLocal
...
struct { // dictionary
struct { // XML string list
WS_XML_STRING firstFieldName;
WS_XML_STRING firstFieldNS;
...
} xmlStrings;
WS_XML_DICTIONARY dict;
} dictionary;
}; // fileNameLocal;
Das Array von WS_XML_STRINGwird als Eine Reihe von Feldern vom Typ WS_XML_STRINGgeneriert, die mit benutzerfreundlichen Namen benannt werden. Der generierte Stub verwendet die benutzerfreundlichen Namen in verschiedenen Beschreibungen zur besseren Lesbarkeit.
Clientproxy für WSDL-Vorgänge
Wsutil.exe generiert einen Clientproxy für alle Vorgänge. Anwendungen können die Methodensignatur mithilfe einer Befehlszeilenoption überschreiben.
HRESULT WINAPI bindingName_SimpleMethod(WS_SERVICE_PROXY *serviceProxy,
WS_HEAP *heap,
int a,
int *b,
int *c,
const WS_CALL_PROPERTY* callProperties,
ULONG callPropertyCount,
const WS_ASYNC_CONTEXT * asyncContext,
WS_ERROR * error )
{
void* argList[] = {&a, &b, &c};
return WsCall(_serviceProxy,
(WS_OPERATION_DESCRIPTION*)&example_wsdlLocalDefinitions.contracts.DefaultBinding_ISimpleService.SimpleMethod.SimpleMethod,
(void **)&_argList,
callProperties,
callPropertyCount,
heap,
asyncContext,
error
);
}
Der Vorgangsaufrufer muss einen gültigen Heap--Parameter übergeben. Ausgabeparameter werden mithilfe des WS_HEAP Werts zugewiesen, der im Heap--Parameter angegeben ist. Die aufrufende Funktion kann den Heap zurücksetzen oder freigeben, um Speicher für alle Ausgabeparameter freizugeben. Wenn der Vorgang fehlschlägt, können zusätzliche Detailfehlerinformationen aus dem optionalen Fehlerobjekt abgerufen werden, wenn er verfügbar ist.
Wsutil.exe generiert einen Dienststub für alle vorgänge, die in bindung beschrieben werden.
HRESULT CALLBACK ISimpleService_SimpleMethodStub(
const WS_OPERATION_CONTEXT *context,
void * stackStruct,
void * callback,
const WS_ASYNC_CONTEXT * asyncContext,
WS_ERROR *error )
{
SimpleMethodParamStruct *pstack = (SimpleMethodParamStruct *) stackstruct;
SimpleMethodOperation operation = (SimpleMethodOperation)callback;
return operation(context, pstack->a, &(pstack->b), &(pstack->c ), asyncContext, error );
}
Im obigen Abschnitt wird der Prototyp der lokalen Struktur beschrieben, die alle lokalen Definitionen nur für die Stubdatei enthält. In den nachfolgenden Abschnitten werden die Definitionen der Beschreibungen beschrieben.
WSDL-Definitionsgenerierung
Wsutil.exe generiert eine konstante statische (statische) Struktur mit dem Namen *<file_name>*LocalDefinitions vom Typ *<service_name>*Local, die alle lokalen Definitionen enthält.
const static _SimpleServiceLocal example_wsdlLocalDefinitions =
{
{ // global types
...
}, // global types
{ // global elements
...
}, // global elements
{ // messages
...
}, //messages
...
{ // dictionary
...
}, // dictionary
},
Die folgenden WSDL-Beschreibungen werden unterstützt:
- wsdl:service
- wsdl:binding
- wsdl:portType
- wsdl:operation
- wsdl:message
Verarbeiten von wsdl:operation und wsdl:message
Jeder im WSDL-Dokument angegebene Vorgang wird einem Dienstvorgang durch Wsutil.exezugeordnet. Das Tool generiert separate Definitionen der Dienstvorgänge sowohl für den Server als auch für den Client.
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://Example.org"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" targetNamespace="http://Example.org"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:portType name="ISimpleService">
<wsdl:operation name="SimpleMethod">
<wsdl:input wsaw:Action="http://Example.org/ISimpleService/SimpleMethod"
message="tns:ISimpleService_SimpleMethod_InputMessage" />
<wsdl:output wsaw:Action="http://Example.org/ISimpleService/SimpleMethodResponse"
message="tns:ISimpleService_SimpleMethod_OutputMessage" />
</wsdl:operation>
</wsdl:portType>
<wsdl:message name="ISimpleService_SimpleMethod_InputMessage">
<wsdl:part name="parameters" element="tns:SimpleMethod" />
</wsdl:message>
<wsdl:message name="ISimpleService_SimpleMethod_OutputMessage">
<wsdl:part name="parameters" element="tns:SimpleMethodResponse" />
</wsdl:message>
</wsdl:definitions>
Das Layout der Eingabe- undOutput-Nachrichtendatenelemente wird vom Tool ausgewertet, um die Serialisierungsmetadaten für die Infrastruktur zusammen mit der tatsächlichen Signatur des resultierenden Dienstvorgangs zu generieren, dem die Eingabe- und Ausgabemeldungen zugeordnet sind.
Die Metadaten für jeden Vorgang innerhalb eines bestimmten portType- verfügen über Eingaben und optional eine Ausgabenachricht, jede dieser Nachrichten wird einem WS_MESSAGE_DESCRIPTIONzugeordnet. In diesem Beispiel sind die Eingabe und die Ausgabemeldung für den Vorgang im portType-Objekt "inputMessageDescription" und optional die outputMessageDescription für die WS_OPERATION_DESCRIPTION zugeordnet.
Für jede WSDL-Nachricht generiert das Tool WS_MESSAGE_DESCRIPTION, die auf die WS_ELEMENT_DESCRIPTION Definition verweist, wie unten gezeigt:
...
{ // message description for ISimpleService_SimpleMethod_InputMessage
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.DefaultBinding_ISimpleServiceISimpleService_SimpleMethod_InputMessageactionName,
(WS_ELEMENT_DESCRIPTION*)&(WS_ELEMENT_DESCRIPTION*)&example_wsdl.globalElements.SimpleMethodReponse
}, // message description for ISimpleService_SimpleMethod_InputMessage
...
Die Nachrichtenbeschreibung bezieht sich auf die Beschreibung des Eingabeelements. Da das Element global definiert ist, verweist die Nachrichtenbeschreibung auf die globale Definition anstelle des lokalen statischen Elements. Wenn das Element in einer anderen Datei definiert ist, generiert Wsutil.exe einen Verweis auf die global definierte Struktur in dieser Datei. Wenn "SimpleMethodResponse" beispielsweise in einer anderen Datei "example.xsd" definiert ist, generiert Wsutil.exe stattdessen Folgendes:
...
{ // message description for ISimpleService_SimpleMethod_InputMessage
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.DefaultBinding_ISimpleServiceISimpleService_SimpleMethod_InputMessageactionName,
(WS_ELEMENT_DESCRIPTION*)&(WS_ELEMENT_DESCRIPTION*)&example_xsd.globalElements.SimpleMethodReponse
}, // message description for ISimpleService_SimpleMethod_InputMessage
...
Jede Nachrichtenbeschreibung enthält die Aktion und die spezifische Elementbeschreibung (ein Feld vom Typ WS_ELEMENT_DESCRIPTION) für alle Nachrichtendatenelemente. Im Fall einer RPC-Formatnachricht oder einer Nachricht mit mehreren Teilen wird ein Wrapperelement erstellt, um die zusätzlichen Informationen zu kapseln.
RPC-Stilunterstützung
Wsutil.exe unterstützt Dokumentformat sowie RPC-Stilvorgänge gemäß der WSDL 1.1-Bindungserweiterung für SOAP 1.2-Spezifikation. RPC- und Literalformatvorgänge werden als WS_RPC_LITERAL_OPERATION markiert. Das Dienstmodell ignoriert den Namen des Antworttextwrapperelements in RPC-/Literalvorgängen.
Wsutil.exe unterstützt keine Codierungsstilvorgänge. Der parameter WS_XML_BUFFER wird für die Codierung von Nachrichten generiert, und Entwickler müssen den undurchsichtigen Puffer direkt auffüllen.
Unterstützung mehrerer Nachrichtenteile
Wsutil.exe unterstützt mehrere Nachrichtenteile in einer Nachricht. Eine mehrteilige Nachricht kann wie folgt angegeben werden:
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://Example.org"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" targetNamespace="http://Example.org"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:message name="ISimpleService_MutipleParts_InputMessage">
<wsdl:part name="part1" element="tns:SimpleElement1" />
<wsdl:part name="part2" element="tns:SimpleElement2" />
</wsdl:message>
</wsdl:definitions>
Wsutil.exe generiert ein WS_STRUCT_TYPE Feld für das Nachrichtenelement, wenn die Nachricht mehrere Teile enthält. Wenn die Nachricht mithilfe der Dokumentformatvorlage dargestellt wird, generiert Wsutil.exe ein Wrapperelement mit Strukturtyp. Das Wrapperelement hat keinen Namen oder einen bestimmten Namespace, und die Wrapperstruktur enthält alle Elemente in allen Teilen als Felder. Das Wrapperelement ist nur für die interne Verwendung vorgesehen und wird nicht im Nachrichtentext serialisiert.
Wenn die Nachricht RPC- oder Literalformatdarstellung verwendet, erstellt Wsutil.exe ein Wrapperelement mit dem Vorgangsnamen als Elementnamen und dem angegebenen Namespace als Dienstnamespace gemäß der WSDL SOAP-Erweiterungsspezifikation. Die Struktur des Elements enthält ein Array von Feldern, die die in den Nachrichtenteilen angegebenen Typen darstellen. Das Wrapperelement wird dem tatsächlichen obersten Element im Nachrichtentext zugeordnet, wie in der SOAP-Spezifikation angegeben.
Auf serverseitiger Seite führt jeder Vorgang zu einer Typbeschreibung des resultierenden Serverdienstvorgangs. Dieser Typedef wird verwendet, um wie zuvor beschrieben auf den Vorgang in der Funktionstabelle zu verweisen. Jeder Vorgang führt auch zur Generierung einer Stubfunktion, die nfrastrukturaufrufe im Auftrag des Delegaten an die tatsächliche Methode aufruft.
typedef HRESULT (CALLBACK *SimpleMethodCallback) (
const WS_OPERATION_CONTEXT* context,
unsigned int a,
unsigned int * b,
unsigned int * c,
const WS_ASYNC_CONTEXT* asyncContext,
WS_ERROR* error
);
Für den SimpleMethod-Vorgang wird der SimpleMethodOperation typedef oben definiert. Beachten Sie, dass die generierte Methode über eine erweiterte Argumentliste mit dem Nachrichtenteil für die Eingabe- und Ausgabemeldung für den SimpleMethod-Vorgang als benannte Parameter verfügt.
Auf clientseitiger Seite wird jeder Vorgang einem Proxydienstvorgang zugeordnet.
HRESULT WINAPI SimpleMethod (
WS_SERVICE_PROXY* serviceProxy,
ws_heap *heap,
unsigned int a,
unsigned int * b,
unsigned int * c,
const WS_ASYNC_CONTEXT* asyncContext,
WS_ERROR* error);
Verarbeiten von wsdl:binding
Das WWSAPI-Dienstmodell unterstützt die BINDUNGSerweiterungSOAP. Für jede Bindung gibt es eine zugeordnete portType-.
Der in der Soap-Bindungserweiterung angegebene Transport ist nur eine Empfehlung. Die Anwendung muss Beim Erstellen eines Kanals Transportinformationen bereitstellen. Derzeit unterstützen wir die WS_HTTP_BINDING und WS_TCP_BINDING Bindungen.
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://Example.org"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" targetNamespace="http://Example.org"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:binding name="DefaultBinding_ISimpleService" type="tns:ISimpleService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="SimpleMethod">
<soap:operation soapAction="http://Example.org/ISimpleService/SimpleMethod"
style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
</wsdl:definitions>
In unserem Beispiel-WSDL-Dokument haben wir nur ein portType- für ISimpleService. Die bereitgestellte SOAP-Bindung gibt den HTTP-Transport an, der als WS_HTTP_BINDING angegeben wird. Beachten Sie, dass diese Struktur keine statische Dekoration aufweist, da diese Struktur für die Anwendung verfügbar sein muss.
Verarbeiten von wsdl:portType
Jede portType- in WSDL besteht aus einem oder mehreren Vorgängen. Der Vorgang sollte mit der SOAP-Bindungserweiterung konsistent sein, die in wsdl:binding angegeben ist.
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://Example.org"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" targetNamespace="http://Example.org"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:portType name="ISimpleService">
<wsdl:operation name="SimpleMethod">
...
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>
In diesem Beispiel enthält der ISimpleService-portType- nur den SimpleMethod-Vorgang. Dies entspricht dem Bindungsabschnitt, in dem nur ein WSDL-Vorgang vorhanden ist, der einer SOAP-Aktion zugeordnet ist.
Da der ISimpleService-portType- nur über einen Vorgang verfügt ( SimpleMethod - die entsprechende Funktionstabelle enthält nur SimpleMethod als Dienstvorgang.
In Bezug auf Metadaten wird jeder portType- von Wsutil.exe einem WS_CONTRACT_DESCRIPTIONzugeordnet. Jeder Vorgang innerhalb eines portType- wird einem WS_OPERATION_DESCRIPTIONzugeordnet.
In diesem Beispiel generiert portType das Tool WS_CONTRACT_DESCRIPTION für ISimpleService. Diese Vertragsbeschreibung enthält die spezifische Anzahl von Vorgängen, die im ISimpleService-portType- verfügbar sind, sowie ein Array von WS_OPERATION_DESCRIPTION, das die einzelnen Vorgänge darstellt, die für den PortType für ISimpleService definiert sind. Da nur ein Vorgang für ISimpleService portType für ISimpleService vorhanden ist, gibt es auch nur eine WS_OPERATION_DESCRIPTION Definition.
... part of LocalDefinitions structure
{ // array of operations for DefaultBinding_ISimpleService
(WS_OPERATION_DESCRIPTION*)&example_wsdlLocalDefinitions.contracts.DefaultBinding_ISimpleService.SimpleMethod.SimpleMethod,
}, // array of operations for DefaultBinding_ISimpleService
{ // contract description for DefaultBinding_ISimpleService
1,
(WS_OPERATION_DESCRIPTION**)example_wsdlLocalDefinitions.contracts.DefaultBinding_ISimpleService.operations,
WS_HTTP_CHANNEL_BINDING,
}, // end of contract description for DefaultBinding_ISimpleService
}, // DefaultBinding_ISimpleService ...
Verarbeiten von wsdl:service
WsUtil.exe verwendet die Dienste, um Bindungs-/Porttypen zu finden, und generiert vertragsstruktur, die Typen, Nachrichten, Porttypdefinitionen usw. beschreibt. Vertragsbeschreibungen sind extern zugänglich und werden als Teil der globalen Definitionsstruktur generiert, die über generierten Header angegeben wird.
WsUtil.exe unterstützt EndpointReference-Erweiterungen, die in wsdl:port definiert sind. Der Endpunktverweis wird in WS-ADDRESSING als Möglichkeit zum Beschreiben Endpunkt- Informationen eines Diensts definiert. Der als WS_XML_STRINGgespeicherte Text der Eingabeendpunktreferenzerweiterung wird zusammen mit übereinstimmenden WS_ENDPOINT_ADDRESS_DESCRIPTION im Abschnitt "endpointReferences" in der globalen Struktur generiert.
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://Example.org"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" targetNamespace="http://Example.org"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:service name="SimpleService">
<wsdl:port name="ISimpleService" binding="tns:DefaultBinding_ISimpleService">
<soap:address location="http://Example.org/ISimpleService" />
<wsa:EndpointReference>
<wsa:Address>http://example.org/wcfmetadata/WSHttpNon</wsa:Address>
</wsa:EndpointReference>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
const _example_wsdl example_wsdl =
{
... // global element description
{// messages
{ // message description for ISimpleService_SimpleMethod_InputMessage
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.ISimpleService_SimpleMethod_InputMessageactionName,
(WS_ELEMENT_DESCRIPTION*)&example_wsdl.globalElements.SimpleMethod,
}, // message description for ISimpleService_SimpleMethod_InputMessage
{ // message description for ISimpleService_SimpleMethod_OutputMessage
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.ISimpleService_SimpleMethod_OutputMessageactionName,
(WS_ELEMENT_DESCRIPTION*)&example_wsdl.globalElements.SimpleMethodResponse,
}, // message description for ISimpleService_SimpleMethod_OutputMessage
}, // messages
{// contracts
{ // DefaultBinding_ISimpleService
1,
(WS_OPERATION_DESCRIPTION**)example_wsdlLocalDefinitions.contracts.DefaultBinding_ISimpleService.operations,
WS_HTTP_CHANNEL_BINDING,
}, // end of DefaultBinding_ISimpleService
}, // contracts
{
{
{ // endpointAddressDescription
WS_ADDRESSING_VERSION_0_9,
},
(WS_XML_STRING*)&xml_string_generated_in_stub // endpointReferenceString
}, //DefaultBinding_ISimpleService
}, // endpointReferences
}
So erstellen Sie WS_ENDPOINT_ADDRESS mithilfe der generierten WsUtil-Metadaten:
WsCreateReader // Create a WS_XML_READER
Initialize a WS_XML_READER_BUFFER_INPUT
WsSetInput // Set the encoding and input of the reader to generate endpointReferenceString
WsReadType // Read WS_ENDPOINT_ADDRESS from the reader
// Using WS_ELEMENT_TYPE_MAPPING, WS_ENDPOINT_ADDRESS_TYPE and generated endpointAddressDescription,
Konstantenzeichenfolgen im Clientproxy- oder Dienst-Stub werden als Felder vom Typ WS_XML_STRING generiert, und es gibt ein Konstantenwörterbuch für alle Zeichenfolgen in der Proxy- oder Stubdatei. Jede Zeichenfolge im Wörterbuch wird als Feld im Wörterbuchteil der lokalen Struktur generiert, um eine bessere Lesbarkeit zu ermöglichen.
... // dictionary part of LocalDefinitions structure
{ // xmlStrings
{ // xmlStrings
WS_XML_STRING_DICTIONARY_VALUE("a",&example_wsdlLocalDefinitions.dictionary.dict, 0),
WS_XML_STRING_DICTIONARY_VALUE("http://Sapphire.org",&example_wsdlLocalDefinitions.dictionary.dict, 1),
WS_XML_STRING_DICTIONARY_VALUE("b",&example_wsdlLocalDefinitions.dictionary.dict, 2),
WS_XML_STRING_DICTIONARY_VALUE("SimpleMethod",&example_wsdlLocalDefinitions.dictionary.dict, 3),
...
}, // end of xmlStrings
{ // SimpleServicedictionary
// 45026280-d5dc-4570-8195-4d66d13bfa34
{ 0x45026280, 0xd5dc, 0x4570, { 0x81, 0x95, 0x4d,0x66, 0xd1, 0x3b, 0xfa, 0x34 } },
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings,
stringCount,
TRUE,
},
}
...
Verarbeiten von wsdl:type
Wsutil.exe unterstützt nur XSD-Dokumente (XML-Schema) in wsdl:type specification. Ein Sonderfall ist, wenn ein Nachrichtenport eine globale Elementdefinition angibt. Weitere Informationen zu den in diesen Fällen verwendeten Heuristiken finden Sie im folgenden Abschnitt.
Parameterverarbeitungs-Heuristiken
Im Dienstmodell werden WSDL-Nachrichten bestimmten Parametern in einer Methode zugeordnet. Wsutil.exe verfügt über zwei Formatvorlagen für die Parametergenerierung: Im ersten Stil verfügt der Vorgang über einen Parameter für die Eingabenachricht und einen Parameter für die Ausgabemeldung (falls erforderlich); im zweiten Stil verwendet Wsutil.exe eine Heuristik zum Zuordnen und Erweitern von Feldern in den Strukturen für Eingabenachrichten und Ausgabemeldungen zu verschiedenen Parametern im Vorgang. Sowohl Eingabe- als auch Ausgabemeldungen müssen Strukturtypnachrichtenelemente aufweisen, um diesen zweiten Ansatz zu generieren.
Wsutil.exe verwendet beim Generieren von Vorgangsparametern aus den Eingabe- und Ausgabemeldungen die folgenden Regeln:
- Bei Eingabe- und Ausgabenachrichten mit mehreren Nachrichtenteilen ist jeder Nachrichtenteil ein separater Parameter im Vorgang, wobei der Nachrichtenteilname als Parametername angegeben ist.
- Bei RPC-Formatnachrichten mit einem Nachrichtenteil ist der Nachrichtenteil ein Parameter im Vorgang, wobei der Nachrichtenteilname als Parametername angegeben ist.
- Für Eingabe- und Ausgabemeldungen im Dokumentstil mit einem Nachrichtenteil:
- Wenn der Name eines Nachrichtenteils "Parameters" lautet und der Elementtyp eine Struktur ist, wird jedes Feld in der Struktur als separater Parameter behandelt, wobei der Feldname der Parametername ist.
- Wenn der Name des Nachrichtenteils nicht "Parameters" lautet, ist die Nachricht ein Parameter im Vorgang mit dem Nachrichtennamen, der als entsprechender Parametername verwendet wird.
- Bei der Eingabe und Ausgabenachricht im Dokumentstil mit einem nillable-Element wird die Nachricht einem Parameter zugeordnet, wobei der Nachrichtenteilname als Parametername angegeben ist. Es wird eine zusätzliche Dereferenzierungsebene hinzugefügt, um anzugeben, dass der Zeiger NULL-werden kann.
- Wenn ein Feld nur im Eingabemeldungselement angezeigt wird, wird das Feld als [in]-Parameter behandelt.
- Wenn ein Feld nur im Ausgabemeldungselement angezeigt wird, wird das Feld als [out]-Parameter behandelt.
- Wenn ein Feld mit demselben Namen und demselben Typ vorhanden ist, der sowohl in der Eingabenachricht als auch in der Ausgabenachricht angezeigt wird, wird das Feld als [in,out]-Parameter behandelt.
Die folgenden Tools werden verwendet, um die Richtung von Parametern zu bestimmen:
- Wenn ein Feld nur im Eingabemeldungselement angezeigt wird, wird das Feld nur als Parameter behandelt.
- Wenn ein Feld nur im Ausgabemeldungselement angezeigt wird, wird das Feld nur als Ausgabeparameter behandelt.
- Wenn ein Feld mit demselben Namen und demselben Typ vorhanden ist, der sowohl in der Eingabenachricht als auch in der Ausgabenachricht angezeigt wird, wird das Feld als In-Out-Parameter behandelt.
Wsutil.exe unterstützt nur sequenzierte Elemente. Sie lehnt eine ungültige Sortierung in Bezug auf [in,out]-Parameter ab, wenn Wsutil.exe die Parameter nicht in einer einzigen Parameterliste kombinieren können. Suffixe können Parameternamen hinzugefügt werden, um Namenskonflikte zu vermeiden.
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://Example.org"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" targetNamespace="http://Example.org"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:message name="ISimpleService_SimpleMethod_InputMessage">
<wsdl:part name="parameters" element="tns:SimpleMethod" />
</wsdl:message>
<wsdl:message name="ISimpleService_SimpleMethod_OutputMessage">
<wsdl:part name="parameters" element="tns:SimpleMethodResponse" />
</wsdl:message>
</wsdl:definitions>
Wsutil.exe berücksichtigt Felder in tns:SimpleMethod und tns:SimpleMethodResponse ato als Parameter, wie in den folgenden Parameterdefinitionen dargestellt:
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://Example.org"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" targetNamespace="http://Example.org"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xs:schema xmlns:tns="http://Example.org" elementFormDefault="qualified"
targetNamespace="http://Example.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://Example.org" />
<xs:element name="SimpleMethod">
<xs:complexType>
<xs:sequence>
<xs:element name="a" type="xs:unsignedInt" />
<xs:element name="b" type="xs:unsignedInt" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SimpleMethodResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="b" type="xs:unsignedInt" />
<xs:element name="c" type="xs:unsignedInt" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
</wsdl:definitions>
Wsutil.exe erweitert die Parameterliste aus den Feldern in der obigen Liste und generiert die ParamStruct Struktur im folgenden Codebeispiel. Die Laufzeit des Dienstmodells kann diese Struktur verwenden, um Argumente an den Client- und Server-Stubs zu übergeben.
typedef struct SimpleMethodParamStruct {
unsigned int a;
unsigned int b;
unsigned int c;
} ;
Diese Struktur wird nur verwendet, um den Stapelframe auf client- und serverseitiger Seite zu beschreiben. Es gibt keine Änderung an der Nachrichtenbeschreibung oder an den Elementbeschreibungen, auf die von der Nachrichtenbeschreibung verwiesen wird.
// following are local definitions for the complex type
{ // field description for a
WS_ELEMENT_FIELD_MAPPING,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aLocalName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aNamespace,
WS_INT32_TYPE,
0,
WsOffsetOf(_SimpleMethod, a),
0,
0,
}, // end of field description for a
{ // field description for b
WS_ELEMENT_FIELD_MAPPING,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.bLocalName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aNamespace,
WS_INT32_TYPE,
0,
WsOffsetOf(_SimpleMethod, b),
0,
0,
}, // end of field description for b
{ // fields description for _SimpleMethod
(WS_FIELD_DESCRIPTION *)&example_wsdlLocalDefinitions.globalElements.SimpleMethod._SimpleMethoddescs.a,
(WS_FIELD_DESCRIPTION *)&example_wsdlLocalDefinitions.globalElements.SimpleMethod._SimpleMethoddescs.b,
},
{ // structure definition
sizeof(_SimpleMethod),
__alignof(_SimpleMethod),
(WS_FIELD_DESCRIPTION**)&example_wsdlLocalDefinitions.globalElements.SimpleMethod._SimpleMethoddescs._SimpleMethodFields,
WsCountOf(example_wsdlLocalDefinitions.globalElements.SimpleMethod._SimpleMethoddescs._SimpleMethodFields),
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings._SimpleMethodTypeName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aNamespace,
0,
}, // struct description for _SimpleMethod
// following are global definitions for the out parameter
...
{ // element description
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings._SimpleMethodTypeName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aNamespace,
WS_STRUCT_TYPE,
(void *)&example_wsdlLocalDefinitions.globalElements.SimpleMethod._SimpleMethoddescs.structDesc,
},
{ // message description for ISimpleService_SimpleMethod_InputMessage
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.ISimpleService_SimpleMethod_InputMessageactionName,
(WS_ELEMENT_DESCRIPTION*)&example_wsdl.globalElements.SimpleMethod,
}, // message description for ISimpleService_SimpleMethod_InputMessage
In der Regel wird eine Ebene der Dereferenzierung für alle Parameter [out] und [in,out] hinzugefügt.
Parameterlose Operation
Bei Dokument- und Literalvorgängen behandelt Wsutil.exe den Vorgang als einen Eingabeparameter und einen Ausgabeparameter, wenn:
- Die Eingabe- oder Ausgabemeldung weist mehr als einen Teil auf.
- Es gibt nur einen Nachrichtenteil, und der Name des Nachrichtenteils ist nicht "Parameter".
.. In dem obigen Beispiel wird vorausgesetzt, dass die Nachrichtenteile ParamIn" und ParamOut-benannt werden, die Methodensignatur wird zum folgenden Code:
typedef struct SimpleMethod{
unsigned int a;
unsigned int b;
};
typedef struct SimpleMethodResponse {
unsigned int b;
unsigned int c;
};
typedef struct ISimpleService_SimpleMethodParamStruct
{
SimpleMethod * SimpleMethod;
SimpleMethodResponse * SimpleMethodResponse;
} ISimpleService_SimpleMethodParamStruct;
Wsutil.exe generiert eine Versionssignatur für die Vorgangsbeschreibung, sodass das WsCall- und serverseitige Servicemodellmodul überprüfen kann, ob die generierte Beschreibung für die aktuelle Plattform anwendbar ist.
Diese Versionsinformationen werden als Teil der WS_OPERATION_DESCRIPTION Struktur generiert. Die Versionsnummer kann als Vereinigungsarmmarkierer behandelt werden, um die Struktur erweiterbar zu machen. Derzeit ist die versionID- ohne nachfolgende Felder auf1 festgelegt. Zukünftige Versiosn kann die Versionsnummer erhöhen und bei Bedarf weitere Felder einschließen. Beispielsweise generiert Wsutil.exe derzeit den folgenden Code basierend auf der Versions-ID:
{ // SimpleMethod
{ // parameter descriptions for SimpleMethod
{ WS_PARAMETER_TYPE_NORMAL, (USHORT)0, (USHORT)-1 },
{ WS_PARAMETER_TYPE_NORMAL, (USHORT)1, (USHORT)-1 },
{ WS_PARAMETER_TYPE_NORMAL, (USHORT)-1, (USHORT)1 },
}, // parameter descriptions for SimpleMethod
{ // operation description for SimpleMethod
1,
(WS_MESSAGE_DESCRIPTION*)&example_wsdl.messages.ISimpleService_SimpleMethod_InputMessage,
(WS_MESSAGE_DESCRIPTION*)&example_wsdl.messages.ISimpleService_SimpleMethod_OutputMessage,
3,
(WS_PARAMETER_DESCRIPTION*)example_wsdlLocalDefinitions.contracts.DefaultBinding_ISimpleService.SimpleMethod.params,
SimpleMethodOperationStub
}, //operation description for SimpleMethod
}, // SimpleMethod
In Zukunft könnte sie wie folgt erweitert werden:
WS_OPERATION_DESCRIPTION simpleMethodOperationDesc =
{
2,
&ISimpleService_SimpleMethod_InputputMessageDesc,
&ISimpleService_SimpleMethod_OutputMessageDesc,
WsCountOf(SimpleMethodParameters),
SimpleMethodParameters,
ISimpleService_SimpleMethod_Stub,
&forwardToString; // just as an example.
};
Sicherheit
Weitere Informationen finden Sie im Abschnitt "Sicherheit" im Wsutil Compiler-Tool Thema.