Share via


XML Serialization with XML Web Services

XML serialization is the underlying transport mechanism used in the XML Web services architecture, performed by the XmlSerializer class. To control the XML generated by an XML Web service, you can apply the attributes listed in both Attributes That Control XML Serialization and Attributes That Control Encoded SOAP Serialization to the classes, return values, parameters, and fields of a file used to create an XML Web service (.asmx). For more information about creating an XML Web service, see Building XML Web Services Using ASP.NET.

Literal and Encoded Styles

The XML generated by an XML Web service can be formatted in either one of two ways, either literal or encoded, as explained in Customizing SOAP Messages. Therefore there are two sets of attributes that control XML serialization. The attributes listed in Attributes That Control XML Serialization are designed to control literal style XML. The attributes listed in Attributes That Control Encoded SOAP Serialization control the encoded style. By selectively applying these attributes, you can tailor an application to return either, or both styles. Furthermore, these attributes can be applied (as appropriate) to return values and parameters.

Example of Using Both Styles

When you're creating an XML Web service, you can use both sets of attributes on the methods. In the following example, the class named MyService contains two XML Web service methods, MyLiteralMethod and MyEncodedMethod. Both methods perform the same function: returning an instance of the Order class. In the Order class, the XmlTypeAttribute and the SoapTypeAttribute attributes are both applied to the OrderID field, and both attributes have their ElementName property set to different values.

To run the example, paste the code into a file with an .asmx extension, and place the file into a virtual directory managed by Internet Information Services (IIS). From an HTML browser, such as Internet Explorer, type the name of the computer, virtual directory, and file.

<%@ 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
[C#]<%@ 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;
    }
}

The following example calls MyLiteralMethod. Note that the element name is changed to "LiteralOrderID".

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <MyLiteralMethodResponse xmlns="https://tempuri.org/">
            <MyLiteralMethodResult>
                <LiteralOrderID>string</LiteralOrderID>
            </MyLiteralMethodResult>
        </MyLiteralMethodResponse>
    </soap:Body>
</soap:Envelope>

The following example calls MyEncodedMethod. Note that the element name is "EncodedOrderID".

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:soapenc="https://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="https://tempuri.org/" xmlns:types="https://tempuri.org/encodedTypes" xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body soap:encodingStyle="https://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>

Applying Attributes to Return Values

You can also apply attributes to return values to control the namespace, element name, and so forth. The following example applies the XmlElementAttribute attribute to the return value of the MyLiteralMethod method. Doing so allows you to control the namespace and element name.

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

When invoked, the code returns XML that resembles the following.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <MyLiteralMethodResponse xmlns="https://tempuri.org/">
            <BookOrder xmlns="https://www.cohowinery.com">
                <LiteralOrderID>string</LiteralOrderID>
            </BookOrder>
        </MyLiteralMethodResponse>
    </soap:Body>
</soap:Envelope>

Attributes Applied to Parameters

You can also apply attributes to parameters to specify namespace, element name and so forth. The following example adds a parameter to the MyLiteralMethodResponse method, and applies the XmlAttributeAttribute attribute to the parameter. The element name and namespace are both set for the parameter.

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

The SOAP request would resemble the following.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <MyLiteralMethod xmlns="https://tempuri.org/">
            <MyOrderID xmlns="https://www.microsoft.com">string</MyOrderID>
        </MyLiteralMethod>
    </soap:Body>
</soap:Envelope>

Applying Attributes to Classes

If you need to control the namespace of elements that correlate to classes, you can apply the XmlTypeAttribute, XmlRootAttribute, and SoapTypeAttribute, as appropriate. The following example applies all three to the Order class.

<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
[C#][XmlType("BigBooksService", Namespace = "https://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;
}

The results of applying the XmlTypeAttribute and SoapTypeAttribute can be seen when you examine the service description, as shown in the following example.

    <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="https://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>

The effect of the XmlRootAttribute can also be seen in the HTTP GET and HTTP POST results, as follows.

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

See Also

XML Serialization | Attributes That Control Encoded SOAP Serialization | Generating SOAP Messages with XML Serialization | Introducing XML Serialization