天天看點

消息(3)——soap,xml及soap序列化器

在上篇随筆中對于客戶執行個體傳遞的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/

轉載請注明:部落格園