当前位置: 移动技术网 > IT编程>开发语言>c# > C#动态webservice调用接口

C#动态webservice调用接口

2019年07月18日  | 移动技术网IT编程  | 我要评论

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 
  } 
} 

以上所述就是本文的全部内容了,希望大家能够喜欢。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网