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 Information Services(IIS)管理的虚拟目录中。 在 Web 浏览器中,键入计算机、虚拟目录和文件的名称。
<%@ 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
[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;
}
应用 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>
</s:complexType>
HTTP GET 和 HTTP POST 结果中也可以看到该 XmlRootAttribute
效果,如下所示。
<?xml version="1.0" encoding="utf-8"?>
<BookOrderForm xmlns="http://tempuri.org/">
<LiteralOrderID>string</LiteralOrderID>
</BookOrderForm>