C#调用Axis2发布的带SoapHeader用户验证的WebService

Posted on 2015-07-19 23:19  laojiahuo  阅读(397)  评论(0编辑  收藏  举报

起因:
合作公司提供了一个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?wsdl
Microsoft(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>

public class WebsiteSoapHeader : System.Web.Services.Protocols.SoapHeader

{

    private string userName=string.Empty;

    private string 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>

    public string UserName

    {

        get { return userName; }

        set { userName = value; }

 

    }

 

    /// <summary>

    ///

    /// </summary>

    public string 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")]

    public partial class InterfaceCls :  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必须与前面的类变量同名

public string GetBuyHouseInfo() {

    object[] results = this.Invoke("GetBuyHouseInfo"new object[0]);

    return ((string)(results[0]));

}

 

 

4、在客户端调用时,增加给Authentication 变量的赋值:

    /// <summary>

/// 测试通过SoapHeader来访问有用户鉴权的服务

/// </summary>

    protected void 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、至此,就解决了前面所说的问题。

Copyright © 2024 laojiahuo
Powered by .NET 9.0 on Kubernetes