国庆长假到了,本想出去玩玩,无奈自己屌丝一枚,啥都没有,只能自己宅在家里思考思考人生。不过人生还是过于复杂,一时间也想不出个所以然,只能是整理一下在工作中遇到的一些小问题,首先是关于带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中的内容也只能是自己解析了。。。
可能遇到后面两种情况的会少一些,希望大家有其他的方式可以分享一下。最后祝大家国庆节快乐!