记一次动态调用WebService

这次的使用参考博客园中的ID是  生命不息,折腾不止 http://www.cnblogs.com/leolion/p/4757320.html ,感谢分享

博客园让自己慢慢的成长,少不了这些无私奉献的大牛,很是感谢。

动态调用的具体步骤为:

1)从目标 URL 下载 WSDL 数据;

2)使用 ServiceDescription 创建和格式化 WSDL 文档文件;

3)使用 ServiceDescriptionImporter 创建客户端代理类;

4)使用 CodeDom 动态创建客户端代理类程序集;

5)利用反射调用相关 WebService 方法。

开始咯

Web.config中的配置,里边的代理类名称好像必须的和WebSevice中的服务名称一样。

<appSettings>
    <!--WebService地址-->
    <add key="WebServiceUrl" value="http://localhost:3933/WebService/InterfaceService.asmx" />
    <!--WebService输出dll文件名称-->
    <add key="OutputDllFilename" value="TestWebService.dll" />
    <!--WebService代理类名称-->
    <add key="ProxyClassName" value="InterfaceService" />
  </appSettings>

创建一个枚举类,把需要映射WebService的方法名称放进去,调用方法的时候用起来方便

 1 namespace WebConnWebService
 2 {
 3     /// <summary>
 4     /// 方法枚举
 5     /// </summary>
 6     public enum EMethod
 7     {
 8         HelloWorld,
 9         CancelOrder,
10         GetAllProductInfo,
11         GetOrderInfo ,
12         GetProductInfo ,
13         OrderSubmit,
14         QueryOrderDetails
15     }
16 }

新建类WSHelper.cs,代码如下,精髓

  1 public class WSHelper
  2     {/// <summary>
  3         /// 输出的dll文件名称
  4         /// </summary>
  5         private static string m_OutputDllFilename;
  6 
  7         /// <summary>
  8         /// WebService代理类名称
  9         /// </summary>
 10         private static string m_ProxyClassName;
 11 
 12         /// <summary>
 13         /// WebService代理类实例
 14         /// </summary>
 15         private static object m_ObjInvoke;
 16 
 17         /// <summary>
 18         /// 接口方法字典
 19         /// </summary>
 20         private static Dictionary<EMethod, MethodInfo> m_MethodDic = new Dictionary<EMethod, MethodInfo>();
 21 
 22         /// <summary>
 23         /// 创建WebService,生成客户端代理程序集文件
 24         /// </summary>
 25         /// <param name="error">错误信息</param>
 26         /// <returns>返回:true或false</returns>
 27         public static bool CreateWebService(out string error)
 28         {
 29             try
 30             {
 31                 error = string.Empty;
 32                 m_OutputDllFilename = ConfigurationManager.AppSettings["OutputDllFilename"];
 33                 m_ProxyClassName = ConfigurationManager.AppSettings["ProxyClassName"];
 34                 string webServiceUrl = ConfigurationManager.AppSettings["WebServiceUrl"];
 35                 webServiceUrl += "?WSDL";
 36 
 37                 // 如果程序集已存在,直接使用
 38                 if (File.Exists(Path.Combine(Environment.CurrentDirectory, m_OutputDllFilename)))
 39                 {
 40                     BuildMethods();
 41                     return true;
 42                 }
 43 
 44                 //使用 WebClient 下载 WSDL 信息。
 45                 WebClient web = new WebClient();
 46                 Stream stream = web.OpenRead(webServiceUrl);
 47 
 48                 //创建和格式化 WSDL 文档。
 49                 if (stream != null)
 50                 {
 51                     // 格式化WSDL
 52                     ServiceDescription description = ServiceDescription.Read(stream);
 53 
 54                     // 创建客户端代理类。
 55                     ServiceDescriptionImporter importer = new ServiceDescriptionImporter
 56                     {
 57                         ProtocolName = "Soap",
 58                         Style = ServiceDescriptionImportStyle.Client,
 59                         CodeGenerationOptions =
 60                             CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync
 61                     };
 62 
 63                     // 添加 WSDL 文档。
 64                     importer.AddServiceDescription(description, null, null);
 65 
 66                     //使用 CodeDom 编译客户端代理类。
 67                     CodeNamespace nmspace = new CodeNamespace();
 68                     CodeCompileUnit unit = new CodeCompileUnit();
 69                     unit.Namespaces.Add(nmspace);
 70 
 71                     ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
 72                     CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
 73 
 74                     CompilerParameters parameter = new CompilerParameters
 75                     {
 76                         GenerateExecutable = false,
 77                         // 指定输出dll文件名。
 78                         OutputAssembly = m_OutputDllFilename
 79                     };
 80 
 81                     parameter.ReferencedAssemblies.Add("System.dll");
 82                     parameter.ReferencedAssemblies.Add("System.XML.dll");
 83                     parameter.ReferencedAssemblies.Add("System.Web.Services.dll");
 84                     parameter.ReferencedAssemblies.Add("System.Data.dll");
 85 
 86                     // 编译输出程序集
 87                     CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit);
 88 
 89                     // 使用 Reflection 调用 WebService。
 90                     if (!result.Errors.HasErrors)
 91                     {
 92                         BuildMethods();
 93                         return true;
 94                     }
 95                     else
 96                     {
 97                         error = "反射生成dll文件时异常";
 98                     }
 99                     stream.Close();
100                     stream.Dispose();
101                 }
102                 else
103                 {
104                     error = "打开WebServiceUrl失败";
105                 }
106             }
107             catch (Exception ex)
108             {
109                 error = ex.Message;
110             }
111             return false;
112         }
113 
114         /// <summary>
115         /// 反射构建Methods
116         /// </summary>
117         private static void BuildMethods()
118         {
119             Assembly asm = Assembly.LoadFrom(m_OutputDllFilename);
120             //var types = asm.GetTypes();
121             Type asmType = asm.GetType(m_ProxyClassName);
122             m_ObjInvoke = Activator.CreateInstance(asmType);
123 
124             //var methods = asmType.GetMethods();
125             var methods = Enum.GetNames(typeof(EMethod)).ToList();
126             foreach (var item in methods)
127             {
128                 var methodInfo = asmType.GetMethod(item);
129                 if (methodInfo != null)
130                 {
131                     var method = (EMethod)Enum.Parse(typeof(EMethod), item);
132                     if (!m_MethodDic.ContainsKey(method))
133                     {
134                         m_MethodDic.Add(method, methodInfo);
135                     }                    
136                 }
137             }
138         }
139 
140         /// <summary>
141         /// 获取请求响应
142         /// </summary>
143         /// <param name="method">方法</param>
144         /// <param name="para">参数</param>
145         /// <returns>返回:Json串</returns>
146         public static string GetResponseString(EMethod method, params object[] para)
147         {
148             string result = null;
149             if (m_MethodDic.ContainsKey(method))
150             {
151                 var temp = m_MethodDic[method].Invoke(m_ObjInvoke, para);
152                 if (temp != null)
153                 {
154                     result = temp.ToString();
155                 }
156             }
157             return result;
158         }
159     }

好了接下来就是调用,简单的测试一下了

1         protected void Page_Load(object sender, EventArgs e)
2         {
3             string error;
4             bool succ = WSHelper.CreateWebService(out error);//先下载wsdl到本地如果本地已下载直接调用本地已下载好的dll,在把方法放到内存中以便调用
5             // SOAP 请求响应方式
6             //TextBox1.Text = WSHelper.GetResponseString(EMethod.Add, Convert.ToInt32(TextBox1.Text), Convert.ToInt32(TextBox2.Text));
7             TextBox1.Text = WSHelper.GetResponseString(EMethod.HelloWorld);
8         }

前台显示

posted @ 2015-10-31 13:45  Materben  阅读(792)  评论(0编辑  收藏  举报