WebService-问题
Posted 随缘梦中人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebService-问题相关的知识,希望对你有一定的参考价值。
1、引用问题
在用C#对接webservice的时候,常用的方法是下载vs中引用webservice的地址。然后,new对应的client就可以使用了。但在,实际应用中往往会遇到webservice访问受限,比如政府单位中内网限制。因此,在开发过程中就会遇到引用问题。
解决办法:
1)使用vs自带的命令生成一个webservice类,是由webservice开发方生成的。推荐,最简单的方式。
2)使用Http请求,去拼接要发送的请求数据xml文档。
3)使用反射,反射出webservice类,得到要请求的方法,再去调用。不推荐,如果是服务端有SoapHeader验证,该方法不适用。
下面对这几种方法进行介绍。
public class WebService1 : System.Web.Services.WebService { public MyHeader myHeader = new MyHeader(); [SoapHeader("myHeader")] [WebMethod] public string HelloWorld(string name, string pwd) { if (myHeader.key != "12") { return JsonConvert.SerializeObject(new { MsgId = 1, Msg = "用户验证成功" }); } if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pwd)) { return JsonConvert.SerializeObject(new { MsgId = 0, Msg = "用户名或密码不能为空" }); } if (name.Equals("admin") && pwd.Equals("admin")) { return JsonConvert.SerializeObject(new { UserName = name, XueYuan = "外语学院", ZhuanYe = "英语专业", Email = "123456@qq.com", Phone = "12345678901", MsgId = 1, Msg = "获取成功" }); } return JsonConvert.SerializeObject(new { MsgId = 0, Msg = "用户名或密码错误" }); } } public class MyHeader : SoapHeader { public string key { get; set; } public string token { get; set; } }
2、服务端生成类方式
命令:wsdl.exe /out:D:/Proxy.cs /order http://localhost:2178/Services.asmx?wsdl
其他语言编写的webservice,有的可能没有.asmx,在地址后面加上?wsdl就可以生成了。
把这个命令复制到vs的自带命令行中生成一个类文件。把这个类文件,发给要调用webservice方。调用方,引用Proxy.cs文件,接着就可以使用了。代码如下:
WebService1 webService1 = new WebService1(); MyHeader myHeader = new MyHeader(); myHeader.key = "12"; webService1.MyHeaderValue = myHeader; Response.Write(webService1.HelloWorld("ad","ad"));
3、Http请求方式
拼接要发送的数据。如下是有SoapHeader和无SoapHeader的数据模板。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> <soapenv:Header/> <soapenv:Body> <tem:HelloWorld> <!--Optional:--> <tem:name>?</tem:name> <!--Optional:--> <tem:pwd>?</tem:pwd> </tem:HelloWorld> </soapenv:Body> </soapenv:Envelope> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> <soapenv:Header> <tem:MySoapHeader> <!--Optional:--> <tem:IN_WSKEY>?</tem:IN_WSKEY> <!--Optional:--> <tem:IN_TOKEN>?</tem:IN_TOKEN> </tem:MySoapHeader> </soapenv:Header> <soapenv:Body> <tem:GetReaderInfo> <!--Optional:--> <tem:certNo>?</tem:certNo> <!--Optional:--> <tem:password>?</tem:password> <tem:certType>?</tem:certType> </tem:GetReaderInfo> </soapenv:Body> </soapenv:Envelope>
把占位符替换为对应的数据就可以了。HttpHelper是发送Http请求的工具类。不同的开发语言开发的webservice,对应的要发送的数据可能不太一样,原理是一样的就是发送http的请求。具体数据,可以通过Soap UI接口调试工具查看。
StringBuilder param = new StringBuilder(); param.Append("<soapenv:Envelope xmlns:soapenv=\\"http://schemas.xmlsoap.org/soap/envelope/\\" xmlns:tem=\\"http://tempuri.org/\\">"); param.Append(" <soapenv:Header><tem:Muse65WSSoapHeader><tem:IN_WSKEY>HxxxxG</tem:IN_WSKEY><tem:IN_TOKEN>6A1FCE13565B7BC4</tem:IN_TOKEN></tem:Muse65WSSoapHeader></soapenv:Header>"); param.Append( "<soapenv:Body><tem:GetReaderInfo><tem:certNo>5807151617</tem:certNo><tem:password>151617</tem:password><tem:certType>2</tem:certType></tem:GetReaderInfo></soapenv:Body>"); param.Append("</soapenv:Envelope>"); HttpHelper httpHelper = new HttpHelper(); httpHelper.SetContentType("text/xml;charset=UTF-8"); httpHelper.SetEncoding(Encoding.UTF8); string str = httpHelper.HttpPost(url, param.ToString()); string res = ""; using (StringReader stringReader = new StringReader(str.Trim())) { using (XmlReader xmlReader = XmlReader.Create(stringReader)) { while (xmlReader.Read()) { if (xmlReader.NodeType == XmlNodeType.Element) { switch (xmlReader.Name.Trim()) { case "GetReaderInfoResult": if (xmlReader.Read()) { res = xmlReader.Value.Trim(); } break; default: break; } } } } }
4、使用反射
不推荐,并且在使用了SoapHeader的webservice中,这种没找到解决办法,不知道怎么传SoapHeader的值。
具体参考:http://www.cnblogs.com/langhua/p/3344784.html
/// < summary> /// 动态调用web服务 /// < /summary> /// < param name="url">WSDL服务地址< /param> /// < param name="classname">类名< /param> /// < param name="methodname">方法名< /param> /// < param name="args">参数< /param> /// < returns>< /returns> public object InvokeWebService(string url, string classname, string methodname, object[] args) { string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling"; if ((classname == null) || (classname == "")) { classname = CommonServiceHelper.GetWsClassName(url); } try { //获取WSDL WebClient wc = new WebClient(); Stream stream = wc.OpenRead(url + "?WSDL"); ServiceDescription sd = ServiceDescription.Read(stream); ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); sdi.AddServiceDescription(sd, "", ""); CodeNamespace cn = new CodeNamespace(@namespace); //生成客户端代理类代码 CodeCompileUnit ccu = new CodeCompileUnit(); ccu.Namespaces.Add(cn); sdi.Import(cn, ccu); CSharpCodeProvider icc = new CSharpCodeProvider(); //设定编译参数 CompilerParameters cplist = new CompilerParameters(); cplist.GenerateExecutable = false; cplist.GenerateInMemory = true; cplist.ReferencedAssemblies.Add("System.dll"); cplist.ReferencedAssemblies.Add("System.XML.dll"); cplist.ReferencedAssemblies.Add("System.Web.Services.dll"); cplist.ReferencedAssemblies.Add("System.Data.dll"); //编译代理类 CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu); if (true == cr.Errors.HasErrors) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors) { sb.Append(ce.ToString()); sb.Append(System.Environment.NewLine); } throw new Exception(sb.ToString()); } //生成代理实例,并调用方法 System.Reflection.Assembly assembly = cr.CompiledAssembly; Type t = assembly.GetType(@namespace + "." + classname, true, true); object obj = Activator.CreateInstance(t); System.Reflection.MethodInfo mi = t.GetMethod(methodname); return mi.Invoke(obj, args); /* * PropertyInfo propertyInfo = type.GetProperty(propertyname); * return propertyInfo.GetValue(obj, null); * */ } catch (Exception ex) { throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace)); } } private static string GetWsClassName(string wsUrl) { string[] parts = wsUrl.Split(\'/\'); string[] pps = parts[parts.Length - 1].Split(\'.\'); return pps[0]; }
以上是关于WebService-问题的主要内容,如果未能解决你的问题,请参考以下文章
C#动态调用webService出现 基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。
当我们在webservice.asmx.cs中编写所有代码时,webservice.asmx有啥用?