C#动态webservice调用接口
程序员文章站
2023-08-22 22:07:27
c#动态webservice调用接口
using system;
using system.collections;
using system.io;...
c#动态webservice调用接口
using system; using system.collections; using system.io; using system.net; using system.text; using system.xml; using system.xml.serialization; namespace hishop.plugins { /// <summary> /// 利用webrequest/webresponse进行webservice调用的类 /// </summary> public class webservicecaller { #region tip:使用说明 //webservices 应该支持get和post调用,在web.config应该增加以下代码 //<webservices> // <protocols> // <add name="httpget"/> // <add name="httppost"/> // </protocols> //</webservices> //调用示例: //hashtable ht = new hashtable(); //hashtable 为webservice所需要的参数集 //ht.add("str", "test"); //ht.add("b", "true"); //xmldocument xx = websvccaller.querysoapwebservice("http://localhost:81/service.asmx", "helloworld", ht); //messagebox.show(xx.outerxml); #endregion /// <summary> /// 需要webservice支持post调用 /// </summary> public static xmldocument querypostwebservice(string url, string methodname, hashtable pars) { httpwebrequest request = (httpwebrequest)httpwebrequest.create(url + "/" + methodname); request.method = "post"; request.contenttype = "application/x-www-form-urlencoded"; setwebrequest(request); byte[] data = encodepars(pars); writerequestdata(request, data); return readxmlresponse(request.getresponse()); } /// <summary> /// 需要webservice支持get调用 /// </summary> public static xmldocument querygetwebservice(string url, string methodname, hashtable pars) { httpwebrequest request = (httpwebrequest)httpwebrequest.create(url + "/" + methodname + "?" + parstostring(pars)); request.method = "get"; request.contenttype = "application/x-www-form-urlencoded"; setwebrequest(request); return readxmlresponse(request.getresponse()); } /// <summary> /// 通用webservice调用(soap),参数pars为string类型的参数名、参数值 /// </summary> public static xmldocument querysoapwebservice(string url, string methodname, hashtable pars) { if (_xmlnamespaces.containskey(url)) { return querysoapwebservice(url, methodname, pars, _xmlnamespaces[url].tostring()); } else { return querysoapwebservice(url, methodname, pars, getnamespace(url)); } } private static xmldocument querysoapwebservice(string url, string methodname, hashtable pars, string xmlns) { _xmlnamespaces[url] = xmlns;//加入缓存,提高效率 httpwebrequest request = (httpwebrequest)httpwebrequest.create(url); request.method = "post"; request.contenttype = "text/xml; charset=utf-8"; request.headers.add("soapaction", "\"" + xmlns + (xmlns.endswith("/") ? "" : "/") + methodname + "\""); setwebrequest(request); byte[] data = encodeparstosoap(pars, xmlns, methodname); writerequestdata(request, data); xmldocument doc = new xmldocument(), doc2 = new xmldocument(); doc = readxmlresponse(request.getresponse()); xmlnamespacemanager mgr = new xmlnamespacemanager(doc.nametable); mgr.addnamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/"); string retxml = doc.selectsinglenode("//soap:body/*/*", mgr).innerxml; doc2.loadxml("<root>" + retxml + "</root>"); adddelaration(doc2); return doc2; } private static string getnamespace(string url) { httpwebrequest request = (httpwebrequest)webrequest.create(url + "?wsdl"); setwebrequest(request); webresponse response = request.getresponse(); streamreader sr = new streamreader(response.getresponsestream(), encoding.utf8); xmldocument doc = new xmldocument(); doc.loadxml(sr.readtoend()); sr.close(); return doc.selectsinglenode("//@targetnamespace").value; } private static byte[] encodeparstosoap(hashtable pars, string xmlns, string methodname) { xmldocument doc = new xmldocument(); doc.loadxml("<soap:envelope xmlns:xsi=\"http://www.w3.org/2001/xmlschema-instance\" xmlns:xsd=\"http://www.w3.org/2001/xmlschema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"></soap:envelope>"); adddelaration(doc); //xmlelement soapbody = doc.createelement_x_x("soap", "body", "http://schemas.xmlsoap.org/soap/envelope/"); xmlelement soapbody = doc.createelement("soap", "body", "http://schemas.xmlsoap.org/soap/envelope/"); //xmlelement soapmethod = doc.createelement_x_x(methodname); xmlelement soapmethod = doc.createelement(methodname); soapmethod.setattribute("xmlns", xmlns); foreach (string k in pars.keys) { //xmlelement soappar = doc.createelement_x_x(k); xmlelement soappar = doc.createelement(k); soappar.innerxml = objecttosoapxml(pars[k]); soapmethod.appendchild(soappar); } soapbody.appendchild(soapmethod); doc.documentelement.appendchild(soapbody); return encoding.utf8.getbytes(doc.outerxml); } private static string objecttosoapxml(object o) { xmlserializer myserializer = new xmlserializer(o.gettype()); memorystream ms = new memorystream(); myserializer.serialize(ms, o); xmldocument doc = new xmldocument(); doc.loadxml(encoding.utf8.getstring(ms.toarray())); if (doc.documentelement != null) { return doc.documentelement.innerxml; } else { return o.tostring(); } } /// <summary> /// 设置凭证与超时时间 /// </summary> /// <param name="request"></param> private static void setwebrequest(httpwebrequest request) { request.credentials = credentialcache.defaultcredentials; request.timeout = 10000; } private static void writerequestdata(httpwebrequest request, byte[] data) { request.contentlength = data.length; stream writer = request.getrequeststream(); writer.write(data, 0, data.length); writer.close(); } private static byte[] encodepars(hashtable pars) { return encoding.utf8.getbytes(parstostring(pars)); } private static string parstostring(hashtable pars) { stringbuilder sb = new stringbuilder(); foreach (string k in pars.keys) { if (sb.length > 0) { sb.append("&"); } //sb.append(httputility.urlencode(k) + "=" + httputility.urlencode(pars[k].tostring())); } return sb.tostring(); } private static xmldocument readxmlresponse(webresponse response) { streamreader sr = new streamreader(response.getresponsestream(), encoding.utf8); string retxml = sr.readtoend(); sr.close(); xmldocument doc = new xmldocument(); doc.loadxml(retxml); return doc; } private static void adddelaration(xmldocument doc) { xmldeclaration decl = doc.createxmldeclaration("1.0", "utf-8", null); doc.insertbefore(decl, doc.documentelement); } private static hashtable _xmlnamespaces = new hashtable();//缓存xmlnamespace,避免重复调用getnamespace } }
//调用并读取解析返回结果 dataset ds = new dataset(); xmlnode xmlnode1; xmldatadocument xd = new xmldatadocument(); stringbuilder sb; hashtable ht = new hashtable(); ht.add("xmlin", "<request><memcode>001</memcode></request>"); xmlnode1 = hishop.plugins.webservicecaller.querysoapwebservice("http://xxx.xxxx.com/service.asmx", "sinpointquery", ht); if (xmlnode1 == null) { return; } string xmlstr= httputility.htmldecode(xmlnode1.outerxml); sb = new stringbuilder(xmlstr); if (sb.tostring().equals("")) { return; } xd.loadxml(sb.tostring()); ds.readxml(new xmlnodereader(xd)); //ds可以返回出结果集
示例二:
1.动态调用的方法:
/// <summary> /// 动态webservice调用 /// </summary> /// <returns>string</returns> public string wstest() { string url = "http://localhost:8080/mywebservicetest/services/myservices?wsdl";//wsdl地址 string name = "wstest";//javawebservice开放的接口 webserviceproxy wsd = new webserviceproxy(url, name); string[] str = { "测试c#调用java的webservice" , "hello webservice"}; string suc = (string)wsd.executequery(name, str); return suc; }
2.动态调用具体类:
using system; using system.collections; using system.componentmodel; using system.data; using system.linq; using system.web; using system.web.services; using system.web.services.protocols; using system.xml.linq; using system.io; using system.net; using system.codedom; using system.codedom.compiler; using system.web.services.description; using system.xml.serialization; using system.web.services.discovery; using system.xml.schema; using system.text; using system.security.cryptography; using system.reflection; using system.collections.generic; using system.xml; namespace tpsvservice { /// <summary> /// webserviceproxy 的摘要说明 /// </summary> [webservice(namespace = "http://tempuri.org/")] [webservicebinding(conformsto = wsiprofiles.basicprofile1_1)] [toolboxitem(false)] // 若要允许使用 asp.net ajax 从脚本中调用此 web 服务,请取消对下行的注释。 // [system.web.script.services.scriptservice] public class webserviceproxy : system.web.services.webservice { #region 私有变量和属性定义 /// <summary> /// web服务地址 /// </summary> private string _wsdlurl = string.empty; /// <summary> /// web服务名称 /// </summary> private string _wsdlname = string.empty; /// <summary> /// 代理类命名空间 /// </summary> private string _wsdlnamespace = "framework.webservice.dynamicwebservicecalling.{0}"; /// <summary> /// 代理类类型名称 /// </summary> private type _typename = null; /// <summary> /// 程序集名称 /// </summary> private string _assname = string.empty; /// <summary> /// 代理类所在程序集路径 /// </summary> private string _asspath = string.empty; /// <summary> /// 代理类的实例 /// </summary> private object _instance = null; /// <summary> /// 代理类的实例 /// </summary> private object instance { get { if (_instance == null) { _instance = activator.createinstance(_typename); return _instance; } else return _instance; } } #endregion #region 构造函数 public webserviceproxy(string wsdlurl) { this._wsdlurl = wsdlurl; string wsdlname = webserviceproxy.getwsclassname(wsdlurl); this._wsdlname = wsdlname; this._assname = string.format(_wsdlnamespace, wsdlname); this._asspath = path.gettemppath() + this._assname + getmd5sum(this._wsdlurl) + ".dll"; this.createserviceassembly(); } public webserviceproxy(string wsdlurl, string wsdlname) { this._wsdlurl = wsdlurl; this._wsdlname = wsdlname; this._assname = string.format(_wsdlnamespace, wsdlname); this._asspath = path.gettemppath() + this._assname + getmd5sum(this._wsdlurl) + ".dll"; this.createserviceassembly(); } #endregion #region 得到wsdl信息,生成本地代理类并编译为dll,构造函数调用,类生成时加载 /// <summary> /// 得到wsdl信息,生成本地代理类并编译为dll /// </summary> private void createserviceassembly() { if (this.checkcache()) { this.inittypename(); return; } if (string.isnullorempty(this._wsdlurl)) { return; } try { //使用webclient下载wsdl信息 webclient web = new webclient(); stream stream = web.openread(this._wsdlurl); servicedescription description = servicedescription.read(stream);//创建和格式化wsdl文档 servicedescriptionimporter importer = new servicedescriptionimporter();//创建客户端代理代理类 importer.protocolname = "soap"; importer.style = servicedescriptionimportstyle.client; //生成客户端代理 importer.codegenerationoptions = codegenerationoptions.generateproperties | codegenerationoptions.generatenewasync; importer.addservicedescription(description, null, null);//添加wsdl文档 //使用codedom编译客户端代理类 codenamespace nmspace = new codenamespace(_assname); //为代理类添加命名空间 codecompileunit unit = new codecompileunit(); unit.namespaces.add(nmspace); this.checkforimports(this._wsdlurl, importer); servicedescriptionimportwarnings warning = importer.import(nmspace, unit); codedomprovider provider = codedomprovider.createprovider("csharp"); compilerparameters parameter = new compilerparameters(); parameter.referencedassemblies.add("system.dll"); parameter.referencedassemblies.add("system.xml.dll"); parameter.referencedassemblies.add("system.web.services.dll"); parameter.referencedassemblies.add("system.data.dll"); parameter.generateexecutable = false; parameter.generateinmemory = false; parameter.includedebuginformation = false; compilerresults result = provider.compileassemblyfromdom(parameter, unit); provider.dispose(); if (result.errors.haserrors) { string errors = string.format(@"编译错误:{0}错误!", result.errors.count); foreach (compilererror error in result.errors) { errors += error.errortext; } throw new exception(errors); } this.copytempassembly(result.pathtoassembly); this.inittypename(); } catch (exception e) { throw new exception(e.message); } } #endregion #region 执行web服务方法 /// <summary> /// 执行代理类指定方法,有返回值 /// </summary> /// <param name="methodname">方法名称</param> /// <param name="param">参数</param> /// <returns>object</returns> public object executequery(string methodname, object[] param) { object rtnobj = null; string[] args = new string[2]; list<string> list = new list<string>(); list<string> list1 = new list<string>(); list<string> list2 = new list<string>(); object[] obj = new object[3]; try { if (this._typename == null) { //记录web服务访问类名错误日志代码位置 throw new typeloadexception("web服务访问类名【" + this._wsdlname + "】不正确,请检查!"); } //调用方法 methodinfo mi = this._typename.getmethod(methodname); if (mi == null) { //记录web服务方法名错误日志代码位置 throw new typeloadexception("web服务访问方法名【" + methodname + "】不正确,请检查!"); } try { if (param == null) rtnobj = mi.invoke(instance, null); else { list.add("hello "); list.add("webservice "); list.add(" ! "); list1.add("i "); list1.add("am "); list1.add("test "); list2.add("do "); list2.add("it "); list2.add("now "); obj[0] = list; obj[1] = list1; obj[2] = list2; rtnobj = mi.invoke(instance, new object[] { obj }); //rtnobj = mi.invoke(instance, new object[] { param }); } } catch (typeloadexception tle) { //记录web服务方法参数个数错误日志代码位置 throw new typeloadexception("web服务访问方法【" + methodname + "】参数个数不正确,请检查!", new typeloadexception(tle.stacktrace)); } } catch (exception ex) { throw new exception(ex.message, new exception(ex.stacktrace)); } return rtnobj; } /// <summary> /// 执行代理类指定方法,无返回值 /// </summary> /// <param name="methodname">方法名称</param> /// <param name="param">参数</param> public void executenoquery(string methodname, object[] param) { try { if (this._typename == null) { //记录web服务访问类名错误日志代码位置 throw new typeloadexception("web服务访问类名【" + this._wsdlname + "】不正确,请检查!"); } //调用方法 methodinfo mi = this._typename.getmethod(methodname); if (mi == null) { //记录web服务方法名错误日志代码位置 throw new typeloadexception("web服务访问方法名【" + methodname + "】不正确,请检查!"); } try { if (param == null) mi.invoke(instance, null); else mi.invoke(instance, param); } catch (typeloadexception tle) { //记录web服务方法参数个数错误日志代码位置 throw new typeloadexception("web服务访问方法【" + methodname + "】参数个数不正确,请检查!", new typeloadexception(tle.stacktrace)); } } catch (exception ex) { throw new exception(ex.message, new exception(ex.stacktrace)); } } #endregion #region 私有方法 /// <summary> /// 得到代理类类型名称 /// </summary> private void inittypename() { assembly serviceasm = assembly.loadfrom(this._asspath); type[] types = serviceasm.gettypes(); string objtypename = ""; foreach (type t in types) { if (t.basetype == typeof(soaphttpclientprotocol)) { objtypename = t.name; break; } } _typename = serviceasm.gettype(this._assname + "." + objtypename); } /// <summary> /// 根据web service文档架构向代理类添加servicedescription和xmlschema /// </summary> /// <param name="basewsdlurl">web服务地址</param> /// <param name="importer">代理类</param> private void checkforimports(string basewsdlurl, servicedescriptionimporter importer) { discoveryclientprotocol dcp = new discoveryclientprotocol(); dcp.discoverany(basewsdlurl); dcp.resolveall(); foreach (object osd in dcp.documents.values) { if (osd is servicedescription) importer.addservicedescription((servicedescription)osd, null, null); ; if (osd is xmlschema) importer.schemas.add((xmlschema)osd); } } /// <summary> /// 复制程序集到指定路径 /// </summary> /// <param name="pathtoassembly">程序集路径</param> private void copytempassembly(string pathtoassembly) { file.copy(pathtoassembly, this._asspath); } private string getmd5sum(string str) { encoder enc = system.text.encoding.unicode.getencoder(); byte[] unicodetext = new byte[str.length * 2]; enc.getbytes(str.tochararray(), 0, str.length, unicodetext, 0, true); md5 md5 = new md5cryptoserviceprovider(); byte[] result = md5.computehash(unicodetext); stringbuilder sb = new stringbuilder(); for (int i = 0; i < result.length; i++) { sb.append(result[i].tostring("x2")); } return sb.tostring(); } /// <summary> /// 是否已经存在该程序集 /// </summary> /// <returns>false:不存在该程序集,true:已经存在该程序集</returns> private bool checkcache() { if (file.exists(this._asspath)) { return true; } return false; } //私有方法,默认取url入口的文件名为类名 private static string getwsclassname(string wsdlurl) { string[] parts = wsdlurl.split('/'); string[] pps = parts[parts.length - 1].split('.'); return pps[0]; } #endregion } }
以上所述就是本文的全部内容了,希望大家能够喜欢。
上一篇: C#操作Clipboard读取剪切板中数据实例详解
下一篇: C#委托现实示例分析