我们都知道,调用WebService可以在工程中对WebService地址进行WEB引用,但是这确实很不方便。我想能够利用配置文件灵活调用WebService。如何实现呢?

用C#通过反射实现动态调用WebService

上代码,先试再说:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Net;
  5. using System.IO;
  6. using System.Web.Services.Description;
  7. using System.CodeDom;
  8. using Microsoft.CSharp;
  9. using System.CodeDom.Compiler;
  10.  
  11. namespace TestCommon
  12. {
  13. public class Webservice
  14. {
  15. /// <summary>
  16. /// 实例化WebServices
  17. /// </summary>
  18. /// <param name="url">WebServices地址</param>
  19. /// <param name="methodname">调用的方法</param>
  20. /// <param name="args">把webservices里需要的参数按顺序放到这个object[]里</param>
  21. public static object InvokeWebService(string url, string methodname, object[] args)
  22. {
  23.  
  24. //这里的namespace是需引用的webservices的命名空间,我没有改过,也可以使用。也可以加一个参数从外面传进来。
  25. string @namespace = "client";
  26. try
  27. {
  28. //获取WSDL
  29. WebClient wc = new WebClient();
  30. Stream stream = wc.OpenRead(url + "?WSDL");
  31. ServiceDescription sd = ServiceDescription.Read(stream);
  32. string classname = sd.Services[0].Name;
  33. ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
  34. sdi.AddServiceDescription(sd, "", "");
  35. CodeNamespace cn = new CodeNamespace(@namespace);
  36.  
  37. //生成客户端代理类代码
  38. CodeCompileUnit ccu = new CodeCompileUnit();
  39. ccu.Namespaces.Add(cn);
  40. sdi.Import(cn, ccu);
  41. CSharpCodeProvider csc = new CSharpCodeProvider();
  42. //ICodeCompiler icc = csc.CreateCompiler();
  43.  
  44. //设定编译参数
  45. CompilerParameters cplist = new CompilerParameters();
  46. cplist.GenerateExecutable = false;
  47. cplist.GenerateInMemory = true;
  48. cplist.ReferencedAssemblies.Add("System.dll");
  49. cplist.ReferencedAssemblies.Add("System.XML.dll");
  50. cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
  51. cplist.ReferencedAssemblies.Add("System.Data.dll");
  52.  
  53. //编译代理类
  54. CompilerResults cr = csc.CompileAssemblyFromDom(cplist, ccu);
  55. if (true == cr.Errors.HasErrors)
  56. {
  57. System.Text.StringBuilder sb = new System.Text.StringBuilder();
  58. foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
  59. {
  60. sb.Append(ce.ToString());
  61. sb.Append(System.Environment.NewLine);
  62. }
  63. throw new Exception(sb.ToString());
  64. }
  65.  
  66. //生成代理实例,并调用方法
  67. System.Reflection.Assembly assembly = cr.CompiledAssembly;
  68. Type t = assembly.GetType(@namespace + "." + classname, true, true);
  69. object obj = Activator.CreateInstance(t);
  70. System.Reflection.MethodInfo mi = t.GetMethod(methodname);
  71.  
  72. return mi.Invoke(obj, args);
  73. }
  74. catch
  75. {
  76. return null;
  77. }
  78. }
  79. }
  80. }

注意:上述代码需要引用如下四个名称空间:
using System.Web.Services.Description;  //WS的描述
//以下几个用于根据描述动态生成代码并动态编译获取程序集
using System.CodeDom;  
using Microsoft.CSharp;
using System.CodeDom.Compiler;

如果你看到这段文字,说明您正使用RSS阅读或转自《一棵树-博客园》,原文地址:http://www.cnblogs.com/atree/p/WebService_dynamic.html

代码相对简单,为什么可以如此调用呢?动态编译后用反射来读取并执行。也许了解反射及如何反射对你会有帮助。

反射提供了封装程序集、模块和类型的对象(Type 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。详细请查看:https://msdn.microsoft.com/zh-cn/library/ms173183(VS.80).aspx

为什么WebServices可以通过反射实现?

WebService在传输过程中是通过WSDL来进行描述的(使用SOAP协议)。因此,我们需要获取WebService的WSDL描述,并通过该描述来动态生成程序集。然后通过反射来获取新生成的程序集,并调用其方法!

以下是MSDN对其的描述:

XML Web services 的接口通常由 Web 服务描述语言 (WSDL) 文件来说明。例如,若要获取有关使用 http://localhost/service.asmx 处公开的 ASP.NET 的 Web 服务的 WSDL 说明,只需导航到 http://localhost/service.asmx?WSDL。使用 ServiceDescriptionImporter 类可以方便地将 WSDL 说明中包含的信息导入到System.CodeDom.CodeCompileUnit 对象。通过调整 Style 参数的值,可以指示 ServiceDescriptionImporter 实例生成客户端代理类(通过透明调用该类可提供 Web 服务的功能)或生成抽象类(该类封装 Web 服务的功能而不实现该功能)。如果将 Style 属性设置为 Client,则 ServiceDescriptionImporter 生成客户端代理类,通过调用这些类来提供说明的 Web 服务的功能。如果将 Style 属性设置为 Server,则 ServiceDescriptionImporter 实例生成抽象类,这些类表示所说明的 XML Web services 的功能而不进行实现。然后,可以通过编写从这些抽象类继承的类来对其进行实现,并实现相关的方法。

了解更多关于WebServices的知识:

C#调用WebService实例和开发

Web Service 的工作原理

MSDN:https://msdn.microsoft.com/zh-cn/library/system.web.services.webservice(VS.80).aspx

用C#通过反射实现动态调用WebService 告别Web引用的更多相关文章

  1. 用C#通过反射实现动态调用WebService 告别Web引用(转载)

    我们都知道,调用WebService可以在工程中对WebService地址进行WEB引用,但是这确实很不方便.我想能够利用配置文件灵活调用WebService.如何实现呢? 用C#通过反射实现动态调用 ...

  2. ASP.NET中WebService的创建和部署以及通过反射动态调用WebService

    一.在ASP.NET中创建WebService 首先我们先创建一个ASP.NET Web 应用程序,此处我们以VS2017为例 点击新创建的项目,右键添加新建项,选择Web服务,输入名称后点击添加 这 ...

  3. 动态调用WebService(C#) (非常实用)

    通常我们在程序中需要调用WebService时,都是通过“添加Web引用”,让VS.NET环境来为我们生成服务代理,然后调用对应的Web服务.这样是使工作简单了,但是却和提供Web服务的URL.方法名 ...

  4. C# .NET 动态调用webservice的三种方式

    转载自 百度文库 http://wenku.baidu.com/link?url=Q2q50wohf5W6UX44zqotXFEe_XOMaib4UtI3BigaNwipOHKNETloMF4ax4W ...

  5. WebService – 2.动态调用WebService

    在本节课程中,将演示如何通过程序动态添加.调用.编译.执行WebService并返回结果. WebService动态调用示意图 WebService相关知识 代码文档对象模型CodeDom的使用 编程 ...

  6. 动态调用WebService(C#)

    通常我们在程序中需要调用WebService时,都是通过“添加Web引用”,让VS.NET环境来为我们生成服务代理,然后调用对应的Web服务.这样是使工作简单了,但是却和提供Web服务的URL.方法名 ...

  7. Web Service学习笔记:动态调用WebService

    原文:Web Service学习笔记:动态调用WebService 多数时候我们通过 "添加 Web 引用..." 创建客户端代理类的方式调用WebService,但在某些情况下我 ...

  8. C# 动态调用 WebService (转)

    在 Visual Studio 中客户端程序可以添加服务引用来调用 WebService,这样 Visual Studio 会生成与之相关的代理类,通过这个代理类可以很方便的访问所需要的服务. 如果服 ...

  9. 动态调用WebService接口的几种方式

    一.什么是WebService? 这里就不再赘述了,想要了解的====>传送门 二.为什么要动态调用WebService接口? 一般在C#开发中调用webService服务中的接口都是通过引用过 ...

随机推荐

  1. springmvc controller junit 测试

    第一次搭建SSM框架,整合SpringMVC完成后进行Controller测试,找资料并解决问题. 下图是我的完整目录: 1 建立UserController类 代码清单 1-1:UserContro ...

  2. 【6_100】Same Tree

    Same Tree Total Accepted: 97481 Total Submissions: 230752 Difficulty: Easy Given two binary trees, w ...

  3. 2015年8月18日,杨学明老师《技术部门的绩效管理提升(研讨会)》在中国科学院下属机构CNNIC成功举办!

    2015年8月18日,杨学明老师为中国网络新闻办公室直属央企中国互联网络中心(CNNIC)提供了一天的<技术部门的绩效管理提升(研讨会)>培训课程.杨学明老师分别从研发绩效管理概述.研发绩 ...

  4. 一个通用的makefile

    # ESDK the makefile setting file - chenwg@20131014 # you can modify "PC = 1" such as " ...

  5. Oracle Ebs R12 SLA与GL关系变化

    http://www.cnblogs.com/bruce_zhao/p/3809886.html Oracle Ebs R12 SLA与GL关系变化 SLA概念:SLA(Subledger Accou ...

  6. SQLSERVER 2012之AlwaysOn -- 同步模式下的网卡性能优化

    本文是基于上一篇<SQLServer 2012之AlwaysOn -- 指定数据同步链路,消除网络抖动导致的提交延迟问题>的问题继续进行优化:具体背景请参照上文:     前后折腾了一个多 ...

  7. WP8:在Unity中使用OpenXLive

    Unity 4.2正式版开始添加了对Windows 8.Windows Phone 8等其他平台的支持,而且开发者可以免费使用Unity引擎来开发游戏了.而作为Windows Phone和Window ...

  8. C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)

    C++11 并发指南已经写了 5 章,前五章重点介绍了多线程编程方面的内容,但大部分内容只涉及多线程.互斥量.条件变量和异步编程相关的 API,C++11 程序员完全可以不必知道这些 API 在底层是 ...

  9. DDD领域驱动设计之运用层代码

    1.DDD领域驱动设计实践篇之如何提取模型 2.DDD领域驱动设计之聚合.实体.值对象 3.DDD领域驱动设计之领域基础设施层 4.DDD领域驱动设计之领域服务 5.整体DEMO代码 什么是运用层,说 ...

  10. mongo(四)索引

    mongo(四)索引 根据这里http://www.cnblogs.com/huangxincheng/archive/2012/02/29/2372699.html   首先,需要构造一些数据,如下 ...