C#呼叫Axis2釋出的帶SoapHeader使用者驗證的WebService(通過測試)
C#呼叫Axis2釋出的帶SoapHeader使用者驗證的WebService
環境: 提供的服務是Axis2開發的,我方用C#呼叫,開發環境是VS2010
起因:合作公司提供了一個WebService供我呼叫,為了保證安全性,要求在SoapHeader中帶使用者名稱和密碼進行校驗。
在獲取了對方的WSDL檔案後,並未在檔案中指明SoapHeader的格式以及要傳遞的使用者名稱、密碼的屬性名稱。按照C#中呼叫WebService的常規方法,在測試工程中“新增Web引用”或“新增服務引用”,只看到生成的*.discomap 和 *.wsdl 兩個檔案,並未找到生成的 *.cs 類檔案,但在測試程式碼中可以直接呼叫
通過對網上一些案例的研究以及自己的摸索,發現一個解決方法。
步驟:
1、通過命令列,使用wsdl.exe工具手工生成服務介面類檔案:
a)開始選單--》Microsoft Visual Studio 2010--》Visual Studio Tools--》Visual Studio Command Prompt (2010)
b)C:\*******\VC>wsdl /n:website /out:D:\******\website\InterfaceCls.cs
c)把生成的InterfaceCls.cs檔案加入工程,例如:App_Code目錄
2、建立自定義SoapHeader檔案,性須繼承自
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
///<summary>
///WebsiteSoapHeader
///</summary>
publicclassWebsiteSoapHeader : System.Web.Services.Protocols.SoapHeader
{
privatestring userName=string.Empty;
privatestring passWord=string.Empty;
///<summary>
///
///</summary>
public WebsiteSoapHeader()
{
}
///<summary>
///
///</summary>
///<param name="userName">使用者名稱</param>
///<param name="passWord">密碼</param>
public WebsiteSoapHeader(string userName, string passWord)
{
this.userName = userName;
this.passWord = passWord;
}
///<summary>
///
///</summary>
publicstring UserName
{
get { return userName; }
set { userName = value; }
}
///<summary>
///
///</summary>
publicstring PassWord
{
get { return passWord; }
set { passWord = value; }
}
}
3、修改InterfaceCls.cs 檔案:
a)增加類變數Authentication:
namespace website {
using System;
using System.Web.Services;
using System.Diagnostics;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Xml.Serialization;
///<remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="InterfaceClsSoap11Binding", Namespace="http://ws.apache.org/axis2")]
publicpartialclassInterfaceCls : System.Web.Services.Protocols.SoapHttpClientProtocol {
private System.Threading.SendOrPostCallback GetBuyHouseInfoOperationCompleted;
private System.Threading.SendOrPostCallback sayHelloOperationCompleted;
public WebsiteSoapHeader Authentication;//這是新增的類變數
///<remarks/>
public InterfaceCls() {
……
}
}
}
b)在有身份校驗要求的服務方法上增加宣告:
///<remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("urn:GetBuyHouseInfo", RequestNamespace="http://ws.apache.org/axis2", ResponseNamespace="http://ws.apache.org/axis2", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("return", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)]
[System.Web.Services.Protocols.SoapHeader("Authentication")]//這是新增的宣告,其中Authentication必須與前面的類變數同名
publicstring GetBuyHouseInfo() {
object[] results = this.Invoke("GetBuyHouseInfo", newobject[0]);
return ((string)(results[0]));
}
4、在客戶端呼叫時,增加給Authentication 變數的賦值:
///<summary>
/// 測試通過SoapHeader來訪問有使用者鑑權的服務
///</summary>
protectedvoid testCallRemoteService()
{
website.InterfaceCls service = new website.InterfaceCls();
//以下紅色部分是新增的程式碼
WebsiteSoapHeader header = new WebsiteSoapHeader();
header.UserName = "testuser";
header.PassWord = "111111";
service.Authentication = header; //給Authentication 賦值
string str = service.GetBuyHouseInfo();
}
5、至此,就解決了前面所說的問題。