1. 程式人生 > >C#呼叫Axis2釋出的帶SoapHeader使用者驗證的WebService(通過測試)

C#呼叫Axis2釋出的帶SoapHeader使用者驗證的WebService(通過測試)


C#呼叫Axis2釋出的帶SoapHeader使用者驗證的WebService

環境: 提供的服務是Axis2開發的,我方用C#呼叫,開發環境是VS2010

起因:合作公司提供了一個WebService供我呼叫,為了保證安全性,要求在SoapHeader中帶使用者名稱和密碼進行校驗。

在獲取了對方的WSDL檔案後,並未在檔案中指明SoapHeader的格式以及要傳遞的使用者名稱、密碼的屬性名稱。按照C#中呼叫WebService的常規方法,在測試工程中“新增Web引用”或“新增服務引用”,只看到生成的*.discomap 和 *.wsdl 兩個檔案,並未找到生成的 *.cs 類檔案,但在測試程式碼中可以直接呼叫

WebService,未要求身份校驗的服務方法可以正常呼叫,但對於有身份校驗要求的方法,則無法設定SoapHeader,導致呼叫失敗。

通過對網上一些案例的研究以及自己的摸索,發現一個解決方法。

步驟:

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 

http://XXX.XXX.XXX.XXX:81/axis2/services/InterfaceCls?wsdlMicrosoft(R) Web Services 描述語言實用工具[Microsoft (R) .NET Framework, Version 4.0.30319.1]Copyright (C) Microsoft Corporation. All rights reserved.正在寫入檔案“D:\******\website\InterfaceCls.cs”。

c)把生成的InterfaceCls.cs檔案加入工程,例如:App_Code目錄

2、建立自定義SoapHeader檔案,性須繼承自

System.Web.Services.Protocols.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、至此,就解決了前面所說的問題。