.net 在不同情况下调用带soapheader的webservice的方式

国庆长假到了,本想出去玩玩,无奈自己屌丝一枚,啥都没有,只能自己宅在家里思考思考人生。不过人生还是过于复杂,一时间也想不出个所以然,只能是整理一下在工作中遇到的一些小问题,首先是关于带soapheader的webservice。

一、webservice大家都用的比较频繁,有时也有一些带soapheader的webservice,首先一种最简单的调用soapheader的情况就是,如果对方的webservice也是用.net写的,可能会是这种方式

     [WebMethod]
        [SoapHeader("Header")]
        public string HelloWorld()
        {
            if (Header.username == "admin" && Header.password == "123")
            {
                return "Hello World";
            }
            else
            {
                throw new Exception("验证失败");
            }
        }

        public class AuthHeader : SoapHeader
        {
            public string username;
            public string password;
        }

之后我们在通过添加服务引用或者是利用vs的wsdl工具生成代理类,都会把上面的AuthHeader类型给生成好,我们要做的就是简单的赋值工作了

public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            //要调用的webservice的类型,自动生成在代理类中
            SoapHeaderTest soapTest = new SoapHeaderTest();
            //要调用的soapheader的类型,自动生成在代理类中
            AuthHeader authHeader = new AuthHeader();
            authHeader.username = "admin";
            authHeader.password = "123";
            soapTest.AuthHeaderValue = authHeader;
            string content = soapTest.HelloWorld();
            context.Response.Write(content);
        }

通过这种方式就可以通过验证调用webservice获取返回信息了。

二、有些时候我们发现我们调用对方的webservice一直失败,然后添加的服务引用或者是代理类中也没有soapheader的类型,然后客户告诉我们,你要调用接口必须传soapHeader,这个soapHeader在.net中是这样的

    [DataContract(Namespace = "http://xxx.xxx.xxxxx")]
    public class AuthHeader
    {
        public string username { get; set; }
        public string password { get; set; }
    }

我们把这个AuthHeader按照上面的格式写好。然后在调用webservice中的方法之前加上我们的soapheader,代码如下:

        //添加服务引用生成的类型
            SoapTestService.SoapHeaderTestSoapClient client = new SoapTestService.SoapHeaderTestSoapClient();
            //客户告诉我们AuthHeader的类型,然后自己在程序中对应写出来
            AuthHeader header = new AuthHeader();
            header.username = "admin";
            header.password = "123";
            //开始加入监控头信息
            AddressHeader soapheader = AddressHeader.CreateAddressHeader("AuthHeader",  // Header Name
                                       "http:xxx.xxx.xxxxx",//地址头的命名空间
                                       header);//传人的AuthHeader
            EndpointAddressBuilder eab = new EndpointAddressBuilder(client.Endpoint.Address);
            eab.Headers.Add(soapheader);//将地址头加入进去
            client.Endpoint.Address = eab.ToEndpointAddress();
            //结束加入监控头信息

之后在调用webservice的方法就可以成功调用并获取返回内容了。

三、最后一种情况就是人家只告诉你需要加一个这样的

<AuthHeader>

<username>用户名</username>

<password>密码</password>

</AuthHeader>

这个时候就需要使用我们的SoapUI了,我们来用soapui看看我们报文吧

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
   <soap:Header/>
   <soap:Body>
      <tem:HelloWorld/>
   </soap:Body>
</soap:Envelope>

发现怎么<soap:Header/>中是空的呢,然后我们按照别人给的格式将soapheader中填上

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
   <soap:Header>
      <AuthHeader>
         <username>admin</username>
         <password>123</password>
      </AuthHeader>
   </soap:Header>
   <soap:Body>
      <tem:HelloWorld/>
   </soap:Body>
</soap:Envelope>

然后这样发送过去,发现webservice成功访问并且接收到返回值了,哎,任务时间比较紧迫,只能用最简单也是最笨的方法了,替换数据然后在把报文发过去

 string url = ConfigurationManager.AppSettings["ContractWebService"].ToString();
                                //通过webservice的地址创建HttpWebRequest
                                var webRequest = (HttpWebRequest)WebRequest.Create(new Uri(url));
                                webRequest.Accept = "text/xml";
                                webRequest.Method = "POST";//请求方式,必须写
                                //将请求报文写进去
                                using (var requestStream = webRequest.GetRequestStream())
                                {
                                    using (var textWriter = new StreamWriter(requestStream))
                                    {
                                        textWriter.Write(SoapXml);//这里的soapxml就是我们要发送报文的字符串
                                    }
                                }
                                //发出请求并且获取响应信息
                                WebResponse wr = webRequest.GetResponse();
                                string retString = "";
                                //将返回的xml格式的报文取出
                                using (Stream myResponseStream = wr.GetResponseStream())
                                {
                                    using (StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("UTF-8")))
                                    {
                                         retString = myStreamReader.ReadToEnd();
                                    }
                                }

最终返回的xml中的内容也只能是自己解析了。。。

可能遇到后面两种情况的会少一些,希望大家有其他的方式可以分享一下。最后祝大家国庆节快乐!

时间: 2024-10-09 11:18:10

.net 在不同情况下调用带soapheader的webservice的方式的相关文章

Django在不启动server的情况下调用方法

from django.conf import settingsfrom django import template settings.configure() a = template.Template('My name is {{ name }}.') b = template.Context({"name":"xiaol"}) print a.render(b)

android 设备在设置节能模式的情况下 调用 Toast 会 唤醒屏幕 突然变亮

最近在开发中遇到题目所说的问题 特此记录一下 首先,设备设置从不休眠,设置节能模式为15秒(即:15秒后设备亮度变暗) 然后,进入我们开发的应用,在我们开发的应用中会定时执行某项上传任务,当网络未连接时,会提示用户 "网络未连接,请检查网络" 如果用 Toast.makeText(NetWorkErrorActivity.this, "网络未连接,请检查网络",Toast.LENGTH_SHORT).show(); 这样提示的话 会唤醒屏幕  ,因为会定时执行任务,

C#/PHP调用有SoapHeader的WebService

日前调用第三方WebService接口时遇到了SoapHeader验证的问题,记录一下解决方法. 接口需要的格式: <soapenv:Header> <ReqSOAPHeader xmlns="http://xxx.com"> <appKey>key</appKey> <authKey>pwd</authKey> </ReqSOAPHeader> <soapenv:Header> C#: /

不停MySQL服务情况下增加从库两种常用方式

现在生产环境MySQL数据库是一主一从,由于业务量访问不断增大,故再增加一台从库.前提是不能影响线上业务使用,也就是说不能重启MySQL服务,为了避免出现其他情况,选择在网站访问量低峰期时间段操作. 一般在线增加从库有两种方式,一种是通过mysqldump备份主库,恢复到从库,mysqldump是逻辑备份,数据量大时,备份速度会很慢,锁表的时间也会很长.另一种是通过xtrabackup工具备份主库,恢复到从库,xtrabackup是物理备份,备份速度快,不锁表.为什么不锁表?因为自身会监控主库日

asp.net 调用带证书的webservice解决办法

最近在朋友弄一个调整省政府政务工作流的程序.. 需要把当前的信息推送到政务网上,采用的是带证书的https webservice.. 下面说一下实现过程 第一步,引用webservice地址,删除web.config中相关配置.同时安装好证书 用如下数据替换: [html] view plain copy <system.serviceModel> <bindings> <customBinding> <binding name="IServiceSoa

x86 x64下调用约定浅析

x86平台下调用约定 我们都知道x86平台下常用的有三种调用约定,__cdecl.__stdcall.__fastcall.我们分别对这三种调用约定进行分析. __cdecl __cdecl是C/C++的默认调用约定,如果不显示声明调用约定的情况下,就是该调用约定.下面我们来从汇编层次来熟悉这种调用约定. 我写了一个函数,如下: 1 int __cdecl TestCdecl(int a, int b, int c, int d, int e) 2 { 3 return a + b + c +

c++中六种构造函数的实现以及9中情况下,构造函数的调用过程

六种构造函数的实现代码如下: #include<iostream> using namespace std; //c++中六种默认的构造函数 class Test { public: Test(int d = 0):m_data(d)//1构造函数(带默认值0),以参数列表的形式初始化 { cout<<"Creat Test Obj :"<<this<<endl; } ~Test()//2析构函数 { cout<<"

关于在gridview中有dorpdownlist的情况下使用自带编辑模板的方法

今天记录一下在gridview中,如果有dropdownlist的情况下使用gridview自带编辑模式的方法. 好吧,今天的这个问题有点绕,详细解释一下目的. 因为gridview中的某些列的数据是从basedata里面带出来的,在编辑gridview的时候,user是想手动选择列值,而不是手动输入(输入不对的话,系统会报错),以上是背景. OK,想了想,在gridview中可以这样实现这个功能,用gridview自带的编辑模板,数据呈现用label绑定,数据编辑的时候用dropdownlis

layoutSubviews在以下情况下会被调用

1.init初始化不会触发layoutSubviews2.addSubview会触发layoutSubviews3.设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化4.滚动一个UIScrollView会触发layoutSubviews5.旋转Screen会触发父UIView上的layoutSubviews事件6.改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件 7.直接调用setLayoutSubvie