在使用 C# 開發 Web Services 的時候,有時難免客戶的資訊單位會要求在 SOAP 的 Header 中夾帶一些資訊過去,通常可能會拿來做為驗證或者其他用途,這邊筆者簡單的說明一下使用 .NET 如何實作這個部分
在使用 C# 開發 Web Services 的時候,有時難免客戶的資訊單位會要求在 SOAP 的 Header 中夾帶一些資訊過去,通常可能會拿來做為驗證或者其他用途,這邊筆者簡單的說明一下使用 .NET 如何實作這個部分。
(一)、首先,在服務的地方,自定義一個繼承 SoapHeader 的類別,重點是這個類別的變數必須是 public 且在這個 WebService的 Service1 這個類別裡面,並在公開出 [WebMethod] 的那個方法上 SoapHeader 的 Attribute:
1: public class Service1 : System.Web.Services.WebService
2: {
3: public MySoapHeader soapHeader;
4:
5: [WebMethod]
6: [SoapHeader("soapHeader", Direction = SoapHeaderDirection.InOut)]
7: public WCO.Address QueryUserInfo()
8: {
9: //取得使用者資訊
10: }
11: }
12:
13: public class MySoapHeader : SoapHeader
14: {
15: public string ID = string.Empty;
16: public string Password = string.Empty;
17: public DateTime MakeDate;
18: }
還有一個重點,Attribute 中的第一個參數必須與店數名稱一模一樣。
公開在 Service1 的 MySoapHeader 會在用戶端所參照的 WSDL 取得相關的資訊供傳遞。
這時用戶端叫用服務時,在 SOAP Header 都會夾帶這三個欄位至服務端:
1: POST /Service1.asmx HTTP/1.1
2: Host: localhost
3: Content-Type: text/xml; charset=utf-8
4: Content-Length: length
5: SOAPAction: "http://tempuri.org/QueryUserInfo"
6:
7: <?xml version="1.0" encoding="utf-8"?>
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/">
9: <soap:Header>
10: <MySoapHeader xmlns="http://tempuri.org/">
11: <ID>string</ID>
12: <Password>string</Password>
13: <MakeDate>dateTime</MakeDate>
14: </MySoapHeader>
15: </soap:Header>
16: <soap:Body>
17: <QueryUserInfo xmlns="http://tempuri.org/" />
18: </soap:Body>
19: </soap:Envelope>
服務端的程式碼要能夠處理 MySoapHeader 並加以處理,如果取不到定義在 MySoapHeader 中的 ID & Password 則傳回錯誤訊息,以 IE 執行結果如下:
實作上面結果的服務端程式碼,首先:
1. 定義迴傳型別 Address
2. 並在回傳的 Address 類別中增加一個 ERR_INFO 欄位存放錯誤訊息
1: [Serializable]
2: public class Address
3: {
4: public Address() { }
5:
6: public string Line { get; set; }
7: public string tw_ChineseLine { get; set; }
8: [XmlElement("ERROR_MESSAGE")]
9: public string ErrInfo { get; set; }
10: }
3. 撰寫 QueryUserInfo 的 Web Method
1: [WebMethod]
2: [SoapHeader("soapHeader", Direction = SoapHeaderDirection.InOut)]
3: public WCO.Address QueryUserInfo()
4: {
5: WCO.Address address = null;
6: if (soapHeader == null)
7: {
8: //自訂錯誤訊息:無權限存取
9: address = new WCO.Address() { ErrInfo = "錯誤:必須輸入帳號密碼。"};
10: return address;
11: }
12:
13: if (soapHeader.ID.Trim() == "" || soapHeader.Password.Trim() == "")
14: {
15: address = new WCO.Address() { ErrInfo = "錯誤:帳號密碼不可以是空白。" };
16: return address;
17: }
18:
19: string ID = soapHeader.ID;
20: string password = clsEncryption.DecryptDES(soapHeader.Password);
21: //略.......進行(帳密)驗證
22: //若驗證通過,則進行後續處理
23:
24: address = new WCO.Address() { Line="180", tw_ChineseLine="60", ErrInfo = null};
25: return address;
26: }
若驗證通過則端看服務端程式碼後續要做何種商業內容,程式碼筆者只節錄部分,因為程式非常的簡單,我們直接看如何實作呼叫端,並傳遞 MySoapHeader 的帳號密碼至服務端。
(二)、實作呼叫端
接下來,就是實作呼叫端,前面提到,在 WSDL 中定義的資訊,在 .NET 參考服務定義後會自動產生 Reference.cs 介面檔,當中就可以使用 MySoapHeader 了。
在撰寫呼叫端傳遞 MySoapHeader 也非常地容易,因為直接當引數傳遞即可 (預設會使用 reference 方式傳遞)
這時筆者只需撰寫如下程式碼將 ID 與 Password 傳入 Service1SoapClient 的 QueryUserInfo
1: private void btnSOAPTest_Click(object sender, EventArgs e)
2: {
3: Service1SoapClient testSoap = new Service1SoapClient();
4: MySoapHeader soapHeader = new MySoapHeader()
5: {
6: ID = txtID.Text,
7: Password = txtPassword.Text!=""?clsEncryption.EncryptDES(txtPassword.Text):"",
8: MakeDate = DateTime.Now
9: };
10: Address result = testSoap.QueryUserInfo(ref soapHeader);
11: List<Address> list = new List<Address>() { result};
12: dataGridView1.DataSource = list;
13: }
如上程式,筆者將資料顯示在 DataGridView 中,如下:
如果沒有傳入密碼,那麼最後一欄我們會得到錯誤訊息。
如上、一個簡單的分享。也許對各位有用。
簽名:
學習是一趟奇妙的旅程
這當中,有辛苦、有心酸、也有成果。有時也會有瓶頸。要能夠繼續勇往直前就必須保有一顆最熱誠的心。
軟體開發之路(FB 社團):https://www.facebook.com/groups/361804473860062/
Gelis 程式設計訓練營(粉絲團):https://www.facebook.com/gelis.dev.learning/
如果文章對您有用,幫我點一下讚,或是點一下『我要推薦』,這會讓我更有動力的為各位讀者撰寫下一篇文章。
非常謝謝各位的支持與愛護,小弟在此位各位說聲謝謝!!! ^_^