zoukankan      html  css  js  c++  java
  • C#动态调用WebService

      用C#调用WebService,一般简单的都是在VS引用里右键添加Web引用,强大的VS就会把所有的代码给你自动生成出来,你要做的就是只要调用就可以了,这里就不详细介绍了。

      先说说我这里的背景,我在做一个软件时,WebService的地址端口等信息不是固定的,会有一个配置文件,用户会自己修改配置文件,这样的话,如果我用自动生成的方式就不可以了,你想啊,我原来WebService的地址是A,你改完之后变成B了,我自动生成的是A的service代码,换成B了还能调用到吗?

      经过各种百度终于找到了动态调用的方法,然后自己改进了一下,如下:

      1 using System;
      2 using System.CodeDom;
      3 using System.CodeDom.Compiler;
      4 using System.Collections.Generic;
      5 using System.IO;
      6 using System.Net;
      7 using System.Web.Services.Description;
      8 using Microsoft.CSharp;
      9 using System.Threading;
     10 
     11 namespace Service
     12 {
     13     public class WebServiceHelp
     14     {
     15         /// <summary>
     16         /// Save assemblys by the specific webservice url
     17         /// </summary>
     18         private static Dictionary<string, System.Reflection.Assembly> Assemblys = new Dictionary<string, System.Reflection.Assembly>();
     19 
     20         /// <summary>
     21         /// Invoke method of web service
     22         /// </summary>
     23         /// <param name="url">service address</param>
     24         /// <param name="className">WebService class name</param>
     25         /// <param name="methodName">Method Name</param>
     26         /// <param name="args">Arguments</param>
     27         /// <returns>Return value</returns>
     28         public static object InvokeWebService(string url, string className, string methodName, params object[] args)
     29         {
     30             string @namespace = "Service";
     31             if (string.IsNullOrEmpty(className))
     32             {
     33                 className = GetWsClassName(url);
     34             }
     35             try
     36             {
     37                 System.Reflection.Assembly assembly = null;
     38                 if (!Assemblys.ContainsKey(url))
     39                 {
     40                     //获取WSDL 
     41                     WebClient wc = new WebClient();
     42                     Stream stream = wc.OpenRead(url + "?WSDL");
     43 
     44                     ServiceDescription sd = ServiceDescription.Read(stream);
     45                     ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
     46                     sdi.AddServiceDescription(sd, "", "");
     47                     CodeNamespace cn = new CodeNamespace(@namespace);
     48                     //生成客户端代理类代码 
     49                     CodeCompileUnit ccu = new CodeCompileUnit();
     50                     ccu.Namespaces.Add(cn);
     51                     sdi.Import(cn, ccu);
     52                     CSharpCodeProvider icc = new CSharpCodeProvider();
     53                     //设定编译参数 
     54                     CompilerParameters cplist = new CompilerParameters();
     55                     cplist.GenerateExecutable = false;
     56                     cplist.GenerateInMemory = true;
     57                     cplist.ReferencedAssemblies.Add("System.dll");
     58                     cplist.ReferencedAssemblies.Add("System.XML.dll");
     59                     cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
     60                     cplist.ReferencedAssemblies.Add("System.Data.dll");
     61                     //编译代理类 
     62                     CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
     63                     if (true == cr.Errors.HasErrors)
     64                     {
     65                         System.Text.StringBuilder sb = new System.Text.StringBuilder();
     66                         foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
     67                         {
     68                             sb.Append(ce.ToString());
     69                             sb.Append(System.Environment.NewLine);
     70                         }
     71                         throw new Exception(sb.ToString());
     72                     }
     73                     //生成代理实例,并调用方法 
     74                     assembly = cr.CompiledAssembly;
     75                     Assemblys[url] = assembly;
     76                 }
     77                 else
     78                 {
     79                     assembly = Assemblys[url];
     80                 }
     81 
     82                 Type t = assembly.GetType(@namespace + "." + className, true, true);
     83                 object obj = Activator.CreateInstance(t);
     84                 System.Reflection.MethodInfo mi = t.GetMethod(methodName);
     85                 return mi.Invoke(obj, args);
     86             }
     87             catch (ThreadAbortException tae)
     88             {
     89                 //Logger.Warn(tae.ToString());
     90                 return null;
     91             }
     92             catch (Exception ex)
     93             {
     94                 //Logger.Error(ex.ToString());
     95                 throw new Exception(ex.Message);
     96             }
     97         }
     98 
     99         private static string GetWsClassName(string wsUrl)
    100         {
    101             string[] parts = wsUrl.Split('/');
    102             string[] pps = parts[parts.Length - 1].Split('.');
    103             return pps[0];
    104         }
    105     }
    106 }

    这里说明一下,开头的Assemblys是用来存放动态编译的Assembly信息,不然的话,每次调用Service方法都要重新生成一边,那是相当的慢啊!

    在调用的时候只要传入相应的信息就可以了,调用时:

    1 public string GetPathByVMID(string vmId)
    2         {
    3             return WebServiceHelp.InvokeWebService(ConfigConstant.ServiceAdress, "VMServiceService", "getPathByVmID", vmId) as string;
    4         }

     ServiceAdress的格式"http://127.0.0.1:8080/services/VMService";

  • 相关阅读:
    Elasticsearch 架构解析与最佳实践
    Redis一键安装脚本
    Android——GridView(网格视图)相关知识总结贴
    Android——TabHost(标签容器)相关知识总结贴
    Android——RatingBar(评价条)相关知识总结贴
    Android——SeekBar(拖动条)相关知识总结贴
    Android——SQLite/数据库 相关知识总结贴
    Android——媒体库 相关知识总结贴
    Android——Broadcast Receive 相关知识总结贴
    Android——进程通信/ AIDL/Message相关知识总结贴
  • 原文地址:https://www.cnblogs.com/lewe/p/3229833.html
Copyright © 2011-2022 走看看