加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

.net动态调用webservice服务

发布时间:2020-12-16 22:44:54 所属栏目:安全 来源:网络整理
导读:在C#程序中,若要调用WebService,一般是采用"添加Web引用"的方式来实现的。但如果此WebService的URL是在程序运行过程中才能获得的,那怎么办呢?那就必须是"动态"调用这个WebService了。 ? 网上有不少关于这方面的例子,总结了一下,主要有两种:(1)每次都动

在C#程序中,若要调用WebService,一般是采用"添加Web引用"的方式来实现的。但如果此WebService的URL是在程序运行过程中才能获得的,那怎么办呢?那就必须是"动态"调用这个WebService了。

?

网上有不少关于这方面的例子,总结了一下,主要有两种:(1)每次都动态调用,(2)将WebService生成为一个本地的DLL,生成客户端的实例。

第一种方法:

我把它放到一个叫WebServiceHelper.cs的类里面了。

[c-sharp]? view plain copy
  1. ///?<summary>???
  2. ????????///?动态调用WebService???
  3. ????????///?</summary>???
  4. ///?<param?name="url">WebService地址</param>???
  5. ///?<param?name="classname">类名</param>???
  6. ///?<param?name="methodname">方法名(模块名)</param>???
  7. ///?<param?name="args">参数列表</param>???
  8. ///?<returns>object</returns>???
  9. ????????public?static?object?InvokeWebService(string?url,?string?classname,153); background-color:inherit; font-weight:bold">string?methodname,153); background-color:inherit; font-weight:bold">object[]?args)??
  10. ????????{??
  11. ????????????string?@namespace?=?"ServiceBase.WebService.DynamicWebLoad";??
  12. ????????????if?(classname?==?null?||?classname?==?"")??
  13. ????????????{??
  14. ????????????????classname?=?WebServiceHelper.GetClassName(url);??
  15. ????????????}??
  16. ????????????//获取服务描述语言(WSDL)???
  17. ????????????WebClient?wc?=?new?WebClient();??
  18. ????????????Stream?stream?=?wc.OpenRead(url?+?"?WSDL");??
  19. ????????????ServiceDescription?sd?=?ServiceDescription.Read(stream);??
  20. ????????????ServiceDescriptionImporter?sdi?=?new?ServiceDescriptionImporter();??
  21. ????????????sdi.AddServiceDescription(sd,?"",?"");??
  22. ????????????CodeNamespace?cn?=?new?CodeNamespace(@namespace);??
  23. ????????????//生成客户端代理类代码???
  24. ????????????CodeCompileUnit?ccu?=?new?CodeCompileUnit();??
  25. ????????????ccu.Namespaces.Add(cn);??
  26. ????????????sdi.Import(cn,?ccu);??
  27. ????????????CSharpCodeProvider?csc?=?new?CSharpCodeProvider();??
  28. ????????????ICodeCompiler?icc?=?csc.CreateCompiler();??
  29. //设定编译器的参数???
  30. ????????????CompilerParameters?cplist?=?new?CompilerParameters();??
  31. ????????????cplist.GenerateExecutable?=?false;??
  32. ????????????cplist.GenerateInMemory?=?true;??
  33. ????????????cplist.ReferencedAssemblies.Add("System.dll");??
  34. ????????????cplist.ReferencedAssemblies.Add("System.XML.dll");??
  35. ????????????cplist.ReferencedAssemblies.Add("System.Web.Services.dll");??
  36. ????????????cplist.ReferencedAssemblies.Add("System.Data.dll");??
  37. //编译代理类???
  38. ????????????CompilerResults?cr?=?icc.CompileAssemblyFromDom(cplist,153); background-color:inherit; font-weight:bold">if?(true?==?cr.Errors.HasErrors)??
  39. ????????????{??
  40. ????????????????System.Text.StringBuilder?sb?=?new?StringBuilder();??
  41. ????????????????foreach?(CompilerError?ce?in?cr.Errors)??
  42. ????????????????{??
  43. ????????????????????sb.Append(ce.ToString());??
  44. ????????????????????sb.Append(System.Environment.NewLine);??
  45. ????????????????}??
  46. ????????????????throw?new?Exception(sb.ToString());??
  47. ????????????}??
  48. //生成代理实例,并调用方法???
  49. ????????????System.Reflection.Assembly?assembly?=?cr.CompiledAssembly;??
  50. ????????????Type?t?=?assembly.GetType(@namespace?+?"."?+?classname,153); background-color:inherit; font-weight:bold">true,153); background-color:inherit; font-weight:bold">true);??
  51. object?obj?=?Activator.CreateInstance(t);??
  52. ????????????System.Reflection.MethodInfo?mi?=?t.GetMethod(methodname);??
  53. return?mi.Invoke(obj,?args);??
  54. ????????}??
  55. ??
  56. private?string?GetClassName(string?url)??
  57. string[]?parts?=?url.Split('/');??
  58. string[]?pps?=?parts[parts.Length?-?1].Split('.');??
  59. return?pps[0];??
  60. ????????}??

举个使用它的例子:

copy

    object[]?args?=?new?object[1];??
  1. ????????????args.SetValue("cyy_JS",?0);??
  2. ????????????DataTable?dt?=?WebServiceHelper.InvokeWebService("http://192.168.0.10/DBMS_CYY/DBMS_Service.asmx",?"GetUserTreeListData",?args)?as?DataTable;??

恩~有点麻烦,这意味着每次我都要把想调用的函数的参数组织成一个object[]才行,且每次调用InvokeWebService都是在内存中创建动态程序集,效率极低。则次种方法绝对没有直接用“实例名.方法名(参数列表)”来的舒服。

第二种方法:

为了提高效率,希望不要每次都创建这么一个动态程序集,那么就要把这个程序集保存在本地,使用的时候调用这个本地的DLL即可。

首先要调用:WebServiceHelper.CreateWebServiceDLL(); 用来在Debug目录下生成dll。这个函数的代码如下:

copy

    void?CreateWebServiceDLL()??
  1. //?1.?使用?WebClient?下载?WSDL?信息。??
  2. ????????????WebClient?web?=?new?WebClient();??
  3. ????????????Stream?stream?=?web.OpenRead("http://192.168.0.10/DBMS_CYY/DBMS_Service.asmx?WSDL");??
  4. //?2.?创建和格式化?WSDL?文档。??
  5. ????????????ServiceDescription?description?=?ServiceDescription.Read(stream);??
  6. //?3.?创建客户端代理代理类。??
  7. ????????????ServiceDescriptionImporter?importer?=?new?ServiceDescriptionImporter();??
  8. ????????????importer.ProtocolName?=?"Soap";?//?指定访问协议。??
  9. ????????????importer.Style?=?ServiceDescriptionImportStyle.Client;?//?生成客户端代理。??
  10. ????????????importer.CodeGenerationOptions?=?CodeGenerationOptions.GenerateProperties?|?CodeGenerationOptions.GenerateNewAsync;??
  11. ????????????importer.AddServiceDescription(description,?null,153); background-color:inherit; font-weight:bold">null);?//?添加?WSDL?文档。??
  12. //?4.?使用?CodeDom?编译客户端代理类。??
  13. ????????????CodeNamespace?nmspace?=?new?CodeNamespace();????????//?为代理类添加命名空间,缺省为全局空间。??
  14. ????????????CodeCompileUnit?unit?=? ????????????unit.Namespaces.Add(nmspace);??
  15. ????????????ServiceDescriptionImportWarnings?warning?=?importer.Import(nmspace,?unit);??
  16. ????????????CodeDomProvider?provider?=?CodeDomProvider.CreateProvider("CSharp");??
  17. ????????????CompilerParameters?parameter?=? ????????????parameter.GenerateExecutable?=? ????????????parameter.OutputAssembly?=?"DBMS_Service.dll";??//?可以指定你所需的任何文件名。??
  18. ????????????parameter.ReferencedAssemblies.Add("System.dll");??
  19. ????????????parameter.ReferencedAssemblies.Add("System.XML.dll");??
  20. ????????????parameter.ReferencedAssemblies.Add("System.Web.Services.dll");??
  21. ????????????parameter.ReferencedAssemblies.Add("System.Data.dll");??
  22. ????????????CompilerResults?result?=?provider.CompileAssemblyFromDom(parameter,?unit);??
  23. if?(result.Errors.HasErrors)??
  24. ????????????????//?显示编译错误信息??
  25. in?result.Errors)??
  26. ????????}??

下面举个使用的例子:

copy

    Assembly?asm?=?Assembly.LoadFrom("DBMS_Service.dll");??
  1. ????????????Type?t?=?asm.GetType("DBMS_Service");??
  2. object?o?=?Activator.CreateInstance(t);??
  3. ????????????MethodInfo?method?=?t.GetMethod("GetUserTreeListData");??
  4. ????????????DataTable?dt?=?method.Invoke(o,?args)? 这种方法的好处就是只用创建一次程序集,但缺点仍是调用函数的方式比较麻烦。

    第二种方法升级版:

    哈哈,这个是我自创的。目的就是为了解决:只创建一次DLL;以类似“实例名.方法名(参数列表)”的方式来调用函数;以这个DLL为模板,若WebService的内容有更新时,可同时更新这个本地的DLL。

    代码如下:

    copy

      ///?<summary>??
    1. ///?根据WebService的URL,生成一个本地的dll,放在C盘下面,例如:C:|DBMS_WebService.dll??
    2. ///?创建人:程媛媛?创建时间:2010-6-21??
    3. ///?</summary>??
    4. ///?<param?name="url">WebService的UR</param>??
    5. ///?<returns></returns>??
    6. void?CreateWebServiceDLL(string?classname?=?WebServiceHelper.GetClassName(url);??
    7. ????????????Stream?stream?=?web.OpenRead(url?+?"?WSDL");??
    8. namespace);? ????????????parameter.OutputAssembly?=?"C://DBMS_Service.dll";??//?可以指定你所需的任何文件名。??
    9. 首先调用CreateWebServiceDLL("http://192.168.0.10/DBMS_CYY/DBMS_Service.asmx")来生成“C:/DBMS_WebService.dll”;

      接着,把这个DLL添加到工程的“引用”当中。

      也许你会问,为什么不直接把DBMS_WebService.dll放在debug下?答案是,当把DBMS_WebService.dll添加为引用时,若在程序运行过程中要更新(包括删了重新创建)它,则会报错。尝试了几次,被我发现,是不能放在Debug下的,其他的任何路径都可以,例如bin目录下都可以,具体原因我不知道...

      既然都把DBMS_WebService.dll添加为引用了,那么便可以先声明它了:

      copy

        static?ServiceBase.WebService.DynamicWebLoad.DBMS_Service?pDBMS_Service;??

      注意:“public static ServiceBase.WebService.DynamicWebLoad.DBMS_Service”是我们调用CreateWebServiceDLL("http://192.168.0.10/DBMS_CYY/DBMS_Service.asmx")的过程中自定的表空间名。

      接下来的事就是,需要一个函数,用来以此DBMS_WebService.dll为模板,用传入的URL来重新生成并覆盖这个DLL,并且,为了省事,直接返回一个ServiceBase.WebService.DynamicWebLoad.DBMS_Service的实例。

      copy

        ??
      1. object?GetWebServiceInstance( ????????????parameter.OutputAssembly?=?"C://DBMS_Service.dll";?//?可以指定你所需的任何文件名。??
      2. ??????????????
      3. ????????????parameter.ReferencedAssemblies.Add("System.dll");??
      4. ????????????parameter.ReferencedAssemblies.Add("System.XML.dll");??
      5. ????????????parameter.ReferencedAssemblies.Add("System.Web.Services.dll");??
      6. ????????????parameter.ReferencedAssemblies.Add("System.Data.dll");??
      7. ????????????CompilerResults?result?=?provider.CompileAssemblyFromDom(parameter,153); background-color:inherit; font-weight:bold">if?(result.Errors.HasErrors)??
      8. ????????????????//?显示编译错误信息??
      9. ????????????????System.Text.StringBuilder?sb?=?new?StringBuilder();??
      10. in?result.Errors)??
      11. ????????????????{??
      12. ????????????????????sb.Append(ce.ToString());??
      13. ????????????????????sb.Append(System.Environment.NewLine);??
      14. ????????????????}??
      15. new?Exception(sb.ToString());??
      16. //生成代理实例??
      17. ????????????System.Reflection.Assembly?assembly?=?Assembly.Load("DBMS_Service");??
      18. ????????????Type?t?=?assembly.GetType(@true);??
      19. object?obj?=?Activator.CreateInstance(t);??
      20. return?obj;??
      21. 一切准备就绪,在主程序中这样使用它:

        copy

          object?o?=?WebServiceHelper.GetWebServiceInstance(this.WebServiceURL);??
        1. pDBMS_Service?=?o?as?ServiceBase.WebService.DynamicWebLoad.DBMS_Service;??
        2. DataTable?dt?=?pDBMS_Service.GetUserTreeListData(this.UserName);??
        ?

        终于写完了。。。

        (编辑:李大同)

        【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读