XML 序列化是 XML Web 服务结构中使用的基础传输机制,它由 XmlSerializer 类执行。要控制由 XML Web 服务生成的 XML,可将控制 XML 序列化的属性和控制编码的 SOAP 序列化的属性中列出的属性应用于在创建 XML Web 服务 (.asmx) 时使用的文件的类、返回值、参数和字段。有关创建 XML Web 服务的更多信息,请参见使用 ASP.NET 的 XML Web 服务。
文本样式和编码样式
XML Web 服务生成的 XML 可以采用文本和编码这两种格式中的任意一种,自定义 SOAP 消息的格式中对此作了讲解。因此,有两组控制 XML 序列化的属性。控制 XML 序列化的属性中列出的属性专门用于控制文本样式 XML。控制编码的 SOAP 序列化的属性中列出的属性控制编码样式。通过有选择性地应用这些属性,可将应用程序调整为返回两种样式中的任一种或同时返回两种。另外,这些属性可(根据需要)应用于返回值和参数。
使用两种样式的示例
当您在创建 XML Web 服务时,可同时使用方法的两组属性。在下面的代码示例中,名为 MyService 的类包含两个 XML Web 服务方法:MyLiteralMethod 和 MyEncodedMethod。两个方法执行同样的功能:返回 Order 类的实例。在 Order 类中,XmlTypeAttribute 和 SoapTypeAttribute 两个特性都应用于 OrderID 字段,两个特性的 ElementName 属性设置为不同的值。
要运行该示例,请将该代码粘贴到带有 .asmx 扩展名的文件中,并将该文件放入由 Internet 信息服务 (IIS) 管理的虚拟目录中。在 HTML 浏览器(如 Internet Explorer)中,键入计算机的名称、虚拟目录名和文件名。
<%@ 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; } }
下面的代码示例调用 MyLiteralMethod。元素名被更改为“LiteralOrderID”。
<?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>
下面的代码示例调用 MyEncodedMethod。元素名为“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>
将属性应用于返回值
还可将属性应用于返回值,以控制命名空间、元素名等。下面的代码示例将 XmlElementAttribute 属性应用于 MyLiteralMethod 方法的返回值。这样做使您得以控制命名空间和元素名。
<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; }
当被调用时,该代码返回类似于以下代码的 XML。
<?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>
将属性应用于参数
还可将属性应用于参数,以指定命名空间、元素名等。下面的代码示例将一个参数添加到 MyLiteralMethodResponse 方法,并将 XmlAttributeAttribute 属性应用于该参数。元素名和命名空间都为该参数进行了设置。
<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; }
SOAP 请求将类似于下面的代码。
<?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>
将属性应用于类
如果需要控制与类相关的元素的命名空间,可根据需要应用 XmlTypeAttribute、XmlRootAttribute 和 SoapTypeAttribute。下面的代码示例将这三个属性都应用于 Order 类。
<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
[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;
}
应用 XmlTypeAttribute 和 SoapTypeAttribute 的结果可在您检查服务描述时看到,如下面的代码示例所示。
<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>
XmlRootAttribute 的效果也可以在 HTTP GET 和 HTTP POST 的结果中看到,如下所示。