WebService本质上是在HTTP或者其他传输协议上传递Xml/Soap消息,只不过.NET Framework通过一些底层支持使它看起来像是一个Object的方法调用(BTW:有人说.NET在WebService上最大的错误就是把WebMethod包装的太像Object方法调用)。
CSDN上有人问如何在WebMethod里直接接收/返回Xml,有人回答说返回String。但是作为String的XML在传输之前会被Encode,'<'会被转换成'<',等等。这样的格式不利于进一步的Schema验证或者interop。正确的做法是在WebMethod里接受/返回XmlElement,.NET Framework能够正确的把这些Xml嵌入对应的SoapBody里面:
[WebMethod]
public XmlElement SayXml(XmlElement param)
{
//...
}
这时候.NET仍然会给传入/传出的Soap消息加上一层包装:
SOAP request:
<soap:Body>
<SayXml xmlns="http://joycode.com/qqchen/webservices/">
<param>xml</param>
</SayXml>
</soap:Body>
SOAP response:
<soap:Body>
<SayXmlResponse xmlns="http://joycode.com/qqchen/webservices/">
<SayXmlResult>xml</SayXmlResult>
</SayXmlResponse>
</soap:Body>
如果我们需要完全控制SoapBody的内容(例如,需要这部分内容符合某个给定的Schema),可以通过SoapDocumentMethod(去掉SayXml和SayXmlResponse)和XmlAnyElement(去掉param和SayXmlResult)两个特性实现,这里是完整的代码和对应的Soap消息模板:
<%@WebService Language="C#" Class="MyServer.MyService" %>
using System.Xml;
using System.Web.Services;
using System.Xml.Serialization;
using System.Web.Services.Protocols;
namespace MyServer
{
[WebService(Namespace="http://joycode.com/qqchen/webservices/")]
public class MyService : System.Web.Services.WebService
{
[WebMethod]
[SoapDocumentMethod(ParameterStyle=SoapParameterStyle.Bare)]
[return: XmlAnyElement]
public XmlElement SayXml([XmlAnyElement]XmlElement param)
{
//...
}
}
}
POST /xml.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://joycode.com/qqchen/webservices/SayXml"
<?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>xml</soap:Body>
</soap:Envelope>HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?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>xml</soap:Body>
</soap:Envelope>
打印 | 张贴于 2004-04-15 03:34:00 | Tag:.NET
留言反馈
If you are sure that there will only be one XmlElement returned from server, you can simply do this:
XmlNode[] nodes = MyService.GetXml();
XmlElement ret = (XmlElement)nodes[0];
However, if you are not sure, you can go through the array and exam elements one by one.
因为这时候wsdl只能表示参数/返回值是String,WebServices开发工具就不能帮你完成参数有效检测。
为什么?
我最近在研究一个"无法schema"的Entity。
(即这个Entity可以包含其他各种的Entity)
<s:any />
给了我启发!
能不能搞个例子给 csdn的 兄弟能共享。再一次谢谢大侠。
sunwanggang1028@126.com