在上篇随筆中對于客戶執行個體傳遞的xml實作中,手動定義了xml的資料格式,如果現在對産品執行個體進行傳遞,那麼還要手動對産品執行個體進行xml進行資料格式化。現在有一套為資料傳遞定義的協定,那就是soap。其實html也是一種資料存儲格式,但html更注重的是表現資料。
(一)Soap是什麼?
Simple Object Access Protocol 簡單對象通路協定。是一種輕量的,簡單的,基于xml的協定。
在W3c中對它是這樣描述的:
它是一種通信協定,用于應用程式之間的能信,它是一種用于發送消息的格式,被設計用來通過網際網路進行通信,它基于xml,獨立于平台,語言,它簡單且可以擴充,它可以允許繞過防火牆。
可以所它認為是一種協定,同時它也是一種消息發送的格式。
(二)soap版本
Soap現在有兩個版本,1.1和1.2版本。1.1版本是2000年5月釋出的文檔中描述的,它其中包含了大量互操作性問題及歧義,導緻解釋時出現偏差。21.2提供了一個更嚴密、更可靠的規範集合,它基于對協定和xml序列化進行綁定的一個抽象模型。(可以找相關協定規範閱讀)
(三)soap組成
現在看一個soap包(soap是一種協定,也是一種用于發送消息的格式,是以可以叫它soap包)。現在通過WS來看看這個soap包是什麼樣子。
建立Web服務,釋出的方法就一個方法:
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
在客戶調用端:
首先生成代理,直接從web服務位址查找服務生成代理,然後調用:
using ws = FirstInstance;
[TestFixture]
public class SoapTest
[Test]
public void TestSimpleSoap()
{
ws.SelfService client = new ws.SelfService();
Console.WriteLine(client.HelloWorld());
測試的列印是正确的,現在進行抓包分析,對Http下的資料包截取有很多現成的工具,也可以自己寫。
這是用戶端請求時的包(http頭省略):
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<HelloWorld xmlns="http://tempuri.org/"
xmlns:a="http://schemas.datacontract.org/2004/07/
UnicodeTest.FirstInstance"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>
</s:Body>
</s:Envelope>
這是服務端響應的包:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<HelloWorldResponse xmlns="http://tempuri.org/">
<HelloWorldResult>Hello World</HelloWorldResult>
</HelloWorldResponse>
</soap:Body>
</soap:Envelope>
這就是soap包。Soap包由封套Envelope組成,也叫信封,信封由一個soap頭和包體組成,其中包體是必須的。
現在對客戶類執行個體進行傳輸。
public Customer GetCustomer()
Customer customer = new Customer
Unid = 13,
CustomerName = "Songjiang",
CreateTime = DateTime.Now,
Telephone = new Call {
Mobile = "1111111",
FirmCall = "2222",
HomeCall = "3333" }
};
return customer;
用戶端:
public void TestCustomerSoap()
ws.Customer customer = new ws.Customer();
customer = client.GetCustomer();
Console.WriteLine(customer.CustomerName);
從WS傳回的soap包是:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<GetCustomerResponse xmlns="http://tempuri.org/">
<GetCustomerResult>
<Unid>13</Unid>
<CustomerName>Songjiang</CustomerName>
<CreateTime>2010-03-31T11:40:52.3125+08:00</CreateTime>
<Telephone>
<HomeCall>3333</HomeCall>
<Mobile>1111111</Mobile>
<FirmCall>2222</FirmCall>
</Telephone>
</GetCustomerResult>
</GetCustomerResponse>
從中可以看到:
<GetCustomerResponse xmlns="http://tempuri.org/">
這部分與上篇中的對客戶類執行個體的xml資料格式化是很相近的。隻是在整個過程中,自己沒有進行顯示的xml格式化。
而由ws進行顯示的xml序列化。
現在看看通過XmlSerializer序列化器進行對客戶類的手動序列化
public void TestSerialize()
Customer customer = new Customer
};
FileStream fs = new FileStream("xmltest.xml", FileMode.Create);
XmlSerializer formatter = new XmlSerializer(typeof(Customer));
formatter.Serialize(fs, customer);
fs.Close();
文檔内容:
<?xml version="1.0"?>
<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<Unid>13</Unid>
<CustomerName>Songjiang</CustomerName>
<CreateTime>2010-03-31T11:55:32.375+08:00</CreateTime>
<Telephone>
<HomeCall>3333</HomeCall>
<Mobile>1111111</Mobile>
<FirmCall>2222</FirmCall>
</Telephone>
</Customer>
更多XmlSerializer的内容請見:
http://www.cnblogs.com/jams742003/archive/2010/03/03/1677288.html這個文檔的内容與上篇中的内容相近。然後再來看看soap序列化器 SoapFormatter
public void TestSoapSerialize()
FileStream fs = new FileStream("xmlSoap.xml", FileMode.Create);
SoapFormatter formatter = new SoapFormatter();
内容為:
<SOAP-ENV:Envelope>
<SOAP-ENV:Body>
<a1:Customer id="ref-1">
<_x003C_Unid_x003E_k__BackingField>
13
</_x003C_Unid_x003E_k__BackingField>
<_x003C_CustomerName_x003E_k__BackingField id="ref-3">
Songjiang
</_x003C_CustomerName_x003E_k__BackingField>
<_x003C_CreateTime_x003E_k__BackingField>
2010-03-31T12:01:08.8750000+08:00
</_x003C_CreateTime_x003E_k__BackingField>
<_x003C_Telephone_x003E_k__BackingField href="#ref-4"/>
</a1:Customer>
<a1:Call>
<_x003C_HomeCall_x003E_k__BackingField id="ref-5">
3333
</_x003C_HomeCall_x003E_k__BackingField>
<_x003C_Mobile_x003E_k__BackingField id="ref-6">
1111111
</_x003C_Mobile_x003E_k__BackingField>
<_x003C_FirmCall_x003E_k__BackingField id="ref-7">
2222
</_x003C_FirmCall_x003E_k__BackingField>
</a1:Call>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
是一個完整的封套(為了排版好看我删除了一些名字空間樣的字串,其實這樣也不好看)。
部落格園大道至簡
http://www.cnblogs.com/jams742003/轉載請注明:部落格園