XML-Serialisierung mit XML-Webdiensten

Bei der XML-Serialisierung handelt es sich um den durch die XmlSerializer-Klasse ausgeführten Transportmechanismus, der die Grundlage für die Architektur der XML-Webdienste ist. Zum Steuern des mit einem XML-Webdienst generierten XML-Streams können Sie sowohl die unter Attribute zur Steuerung der XML-Serialisierung als auch die unter Attribute zur Steuerung der Serialisierung von codiertem SOAP aufgelisteten Attribute auf die Klassen, Rückgabewerte, Parameter und Felder einer Datei anwenden, die zum Erstellen eines XML-Webdiensts (ASMX) verwendet wurden. Weitere Informationen zum Erstellen von XML-Webdiensten finden Sie unter Erstellen von XML-Webdiensten mit ASP.NET.

Literalformat und codiertes Format

Der mit einem XML-Webdienst generierte XML-Stream kann entweder im Literalformat oder codiert formatiert werden, wie unter Anpassen von SOAP-Nachrichtenformatierungen beschrieben. Daher wird die XML-Serialisierung durch zwei Gruppen von Attributen gesteuert. Die unter Attribute zur Steuerung der XML-Serialisierung aufgelisteten Attribute sind für die Steuerung von XML im Literalformat vorgesehen. Durch die unter Attribute zur Steuerung der Serialisierung von codiertem SOAP aufgeführten Attribute wird das codierte Format gesteuert. Durch die gezielte Anwendung dieser Attribute können Sie eine Anwendung so anpassen, dass sie eines dieser Formate oder beide Formate zurückgibt. Zudem können diese Attribute gegebenenfalls auch auf Rückgabewerte und Parameter angewendet werden.

Beispiel für die Verwendung beider Formate

Bei der Erstellung eines XML-Webdienstes können Sie beide Sätze von Attributen auf die Methoden anwenden. Im folgenden Codebeispiel enthält die Klasse MyService die beiden XML-Webdienstmethoden MyLiteralMethod und MyEncodedMethod. Beide Methoden führen dieselbe Funktion aus: Zurückgeben einer Instanz der Order-Klasse. In der Order-Klasse werden sowohl das XmlTypeAttribute-Attribut als auch das SoapTypeAttribute-Attribut auf das OrderID-Feld angewendet. Für beide Attribute wurden hierbei verschiedene Werte für die ElementName-Eigenschaft festgelegt.

Um das Beispiel auszuführen, fügen Sie den Code in eine ASMX-Datei ein, und speichern Sie die Datei in einem virtuellen Verzeichnis, das durch Internetinformationsdienste (Internet Information Services, IIS) verwaltet wird. Geben Sie in einem Webbrowser den Namen des Computers, des virtuellen Verzeichnisses und der Datei ein.

<%@ WebService Language="VB" Class="MyService" %>  
Imports System  
Imports System.Web.Services  
Imports System.Web.Services.Protocols  
Imports System.Xml.Serialization  
Public Class Order  
    ' Both types of attributes can be applied. Depending on which type  
    ' the method used, either one will affect the call.  
    <SoapElement(ElementName:= "EncodedOrderID"), _  
    XmlElement(ElementName:= "LiteralOrderID")> _  
    public OrderID As String  
End Class  
  
Public Class MyService  
    <WebMethod, SoapDocumentMethod> _  
    public Function MyLiteralMethod() As Order
        Dim myOrder As Order = New Order()  
        return myOrder  
    End Function  
    <WebMethod, SoapRpcMethod> _  
    public Function MyEncodedMethod() As Order
        Dim myOrder As Order = New Order()  
        return myOrder  
    End Function  
End Class  
<%@ WebService Language="C#" Class="MyService" %>  
using System;  
using System.Web.Services;  
using System.Web.Services.Protocols;  
using System.Xml.Serialization;  
public class Order {  
    // Both types of attributes can be applied. Depending on which type  
    // the method used, either one will affect the call.  
    [SoapElement(ElementName = "EncodedOrderID")]  
    [XmlElement(ElementName = "LiteralOrderID")]  
    public String OrderID;  
}  
public class MyService {  
    [WebMethod][SoapDocumentMethod]  
    public Order MyLiteralMethod(){  
        Order myOrder = new Order();  
        return myOrder;  
    }  
    [WebMethod][SoapRpcMethod]  
    public Order MyEncodedMethod(){  
        Order myOrder = new Order();  
        return myOrder;  
    }  
}  

Im folgenden Codebeispiel wird MyLiteralMethod aufgerufen. Der Elementname wird in "LiteralOrderID" geändert.

<?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>  
        <MyLiteralMethodResponse xmlns="http://tempuri.org/">  
            <MyLiteralMethodResult>  
                <LiteralOrderID>string</LiteralOrderID>  
            </MyLiteralMethodResult>  
        </MyLiteralMethodResponse>  
    </soap:Body>  
</soap:Envelope>  

Im folgenden Codebeispiel wird MyEncodedMethod aufgerufen. Der Elementname ist "EncodedOrderID".

<?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:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://tempuri.org/" xmlns:types="http://tempuri.org/encodedTypes" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  
    <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">  
        <tns:MyEncodedMethodResponse>  
            <MyEncodedMethodResult href="#id1" />  
        </tns:MyEncodedMethodResponse>  
        <types:Order id="id1" xsi:type="types:Order">  
            <EncodedOrderID xsi:type="xsd:string">string</EncodedOrderID>  
        </types:Order>  
    </soap:Body>  
</soap:Envelope>  

Anwenden von Attributen auf Rückgabewerte

Sie können auch Attribute für Rückgabewerte anwenden, um Namespace, Elementnamen usw. zu steuern. Im folgenden Codebeispiel wird das XmlElementAttribute-Attribut auf den Rückgabewert der MyLiteralMethod-Methode angewendet. Auf diese Weise können Sie den Namespace und den Elementnamen steuern.

<WebMethod, SoapDocumentMethod> _  
public Function MyLiteralMethod() As _  
<XmlElement(Namespace:="http://www.cohowinery.com", _  
ElementName:= "BookOrder")> _  
Order
    Dim myOrder As Order = New Order()  
    return myOrder  
End Function  
[return: XmlElement(Namespace = "http://www.cohowinery.com",  
ElementName = "BookOrder")]  
[WebMethod][SoapDocumentMethod]  
public Order MyLiteralMethod(){  
    Order myOrder = new Order();  
    return myOrder;  
}  

Wenn er aufgerufen wird, gibt der Code einen XML-Stream zurück, der dem folgenden Beispiel ähnelt.

<?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>  
        <MyLiteralMethodResponse xmlns="http://tempuri.org/">  
            <BookOrder xmlns="http://www.cohowinery.com">  
                <LiteralOrderID>string</LiteralOrderID>  
            </BookOrder>  
        </MyLiteralMethodResponse>  
    </soap:Body>  
</soap:Envelope>  

Auf Parameter angewendete Attribute

Sie können Attribute auch auf Parameter anwenden, um Namespace, Elementnamen usw. anzugeben. Im folgenden Beispiel wird der MyLiteralMethodResponse-Methode ein Parameter hinzugefügt und das XmlAttributeAttribute-Attribut auf den Parameter angewendet. Sowohl der Elementname als auch der Namespace werden für den Parameter festgelegt.

<WebMethod, SoapDocumentMethod> _  
public Function MyLiteralMethod(<XmlElement _  
("MyOrderID", Namespace:="http://www.microsoft.com")>ID As String) As _  
<XmlElement(Namespace:="http://www.cohowinery.com", _  
ElementName:= "BookOrder")> _  
Order
    Dim myOrder As Order = New Order()  
    myOrder.OrderID = ID  
    return myOrder  
End Function  
[return: XmlElement(Namespace = "http://www.cohowinery.com",  
ElementName = "BookOrder")]  
[WebMethod][SoapDocumentMethod]  
public Order MyLiteralMethod([XmlElement("MyOrderID",
Namespace="http://www.microsoft.com")] string ID){  
    Order myOrder = new Order();  
    myOrder.OrderID = ID;  
    return myOrder;  
}

Die SOAP-Anforderung sollte etwa folgendermaßen aussehen.

<?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>  
        <MyLiteralMethod xmlns="http://tempuri.org/">  
            <MyOrderID xmlns="http://www.microsoft.com">string</MyOrderID>  
        </MyLiteralMethod>  
    </soap:Body>  
</soap:Envelope>  

Anwenden von Attributen auf Klassen

Um den Namespace von Elementen zu steuern, die in Beziehung zu Klassen stehen, können Sie je nach Elementtyp XmlTypeAttribute, XmlRootAttribute und SoapTypeAttribute anwenden. Im folgenden Codebeispiel werden alle drei Attribute auf die Order-Klasse angewendet.

<XmlType("BigBookService"), _  
SoapType("SoapBookService"), _  
XmlRoot("BookOrderForm")> _  
Public Class Order  
    ' Both types of attributes can be applied. Depending on which  
    ' the method used, either one will affect the call.  
    <SoapElement(ElementName:= "EncodedOrderID"), _  
    XmlElement(ElementName:= "LiteralOrderID")> _  
    public OrderID As String  
End Class  
[XmlType("BigBooksService", Namespace = "http://www.cpandl.com")]  
[SoapType("SoapBookService")]  
[XmlRoot("BookOrderForm")]  
public class Order {  
    // Both types of attributes can be applied. Depending on which  
    // the method used, either one will affect the call.  
    [SoapElement(ElementName = "EncodedOrderID")]  
    [XmlElement(ElementName = "LiteralOrderID")]  
    public String OrderID;  
}  

Die Auswirkungen der Anwendungen von XmlTypeAttribute und SoapTypeAttribute werden erkennbar, wenn Sie die Dienstbeschreibung untersuchen. Dies wird im folgenden Codebeispiel gezeigt.

<s:element name="BookOrderForm" type="s0:BigBookService" />
<s:complexType name="BigBookService">
  <s:sequence>
    <s:element minOccurs="0" maxOccurs="1" name="LiteralOrderID" type="s:string" />
  </s:sequence>

  <s:schema targetNamespace="http://tempuri.org/encodedTypes">
    <s:complexType name="SoapBookService">
      <s:sequence>
        <s:element minOccurs="1" maxOccurs="1" name="EncodedOrderID" type="s:string" />
      </s:sequence>
    </s:complexType>
  </s:schema>
</s:complexType>

Die Auswirkungen des XmlRootAttribute-Attributs werden auch in den HTTP GET- und HTTP POST-Ergebnissen deutlich, wie nachfolgend gezeigt wird.

<?xml version="1.0" encoding="utf-8"?>  
<BookOrderForm xmlns="http://tempuri.org/">  
    <LiteralOrderID>string</LiteralOrderID>  
</BookOrderForm>  

Siehe auch