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";

  • 相关阅读:
    LeetCode 1110. Delete Nodes And Return Forest
    LeetCode 473. Matchsticks to Square
    LeetCode 886. Possible Bipartition
    LeetCode 737. Sentence Similarity II
    LeetCode 734. Sentence Similarity
    LeetCode 491. Increasing Subsequences
    LeetCode 1020. Number of Enclaves
    LeetCode 531. Lonely Pixel I
    LeetCode 1091. Shortest Path in Binary Matrix
    LeetCode 590. N-ary Tree Postorder Traversal
  • 原文地址:https://www.cnblogs.com/lewe/p/3229833.html
Copyright © 2011-2022 走看看