zoukankan      html  css  js  c++  java
  • 初学Web Service笔记之动态调用WebService

    今天刚学习了下动态调用WebService,顺便写在博客上以方便以后自己用到,也分享给大家。

    下面是WebService动态调用示意图

    第一步,新建应用程序类库InvokeWebService,再创建静态类WebServiceHelpers,标记为【1】~【11】的解释在代码的后面,代码如下:

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

     代码中的注解如下

     【1】如果URL后面不加"?WSDL",运行结果就是在调用Web Service,而不是Web服务描述语言(WSDL),界面如下:

          如果URL后面加上"?WSDL",那返回的才是真正的Web服务描述语言(WSDL),运行结果如下:

     【2】    ServiceDescription类提供一种方法,以创建和格式化用于描述 XML Web services 的有效的 Web 服务描述语言 (WSDL) 文档文件,该文件是完整的,具有适当的命名空间、元素和特性。 无法继承此类。

    ServiceDescription.Read 方法 (Stream) 通过直接从 Stream实例加载 XML 来初始化ServiceDescription类的实例。

     【3】    ServiceDescriptionImporter 类 公开一种为 XML Web services 生成客户端代理类的方法。

    ServiceDescriptionImporter.AddServiceDescription 方法 将指定的ServiceDescription添加到要导入的ServiceDescriptions值的集合中。

     【4】   CodeNamespace表示命名空间声明。

     【5】   CodeCompileUnit会提供一个CodeDOM程式圆形的容器,CodeCompileUnit含有一个集合,可以储存含有CodeDOM原始程式码原形,专案参考的组件集合以及专案组件属性集合的CodeNamespace物件。

     【6】   CSharpCodeProvider类提供存取C#程式码产生器和程式码编译器的执行个体。

     【7】   取得C#程式码编译器的执行个体

     【8】   创建编译器的参数实例

     【9】   CompilerResults表示从编译器返回的编译结果。使用指定的编译器设定,根据CodeCompileUnit物件之指定阵列所包含的System.CodeDom树状结构,编译一个组件。

     【10】 Activator类包含特定的方法,用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。无法继承此类Activator.CreateInstance 方法  使用与指定参数匹配程度最高的构造函数创建指定类型的实例。

     【11】 MethodInfo 的实例可以通过调用GetMethods或者Type对象或派生自Type的对象的GetMethod方法来获取,还可以通过调用表示泛型方法定义的 MethodInfo 的MakeGenericMethod方法来获取。

    第二步,新建Web Service应用程序,类名为Service1,类里只有一个方法没什么实际用处主要为了练习,代码如下:

    代码
    1 /// <summary>
    2 /// Service1 的摘要说明
    3 /// </summary>
    4 [WebService(Namespace = "http://tempuri.org/")]
    5 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    6 [ToolboxItem(false)]
    7 public class Service1 : System.Web.Services.WebService
    8 {
    9
    10 [WebMethod]
    11 public string HelloWorld(string Temp1,string Temp2)
    12 {
    13 return "参数1:" + Temp1 + "  参数2:" + Temp2;
    14 }
    15 }

    编译成功后发布到本地服务器,在本例子中发布后Web Service路径为“http://localhost/InvokeService/Service1.asmx ”

    第三步,创建测试应用程序,在测试应用程序里引入第一步生成的DLL,运行后界面如下:

    代码如下:

    代码
    1 private void button1_Click(object sender, EventArgs e)
    2 {
    3 string url = "http://localhost/InvokeService/Service1.asmx";
    4 string[] args = new string[2];
    5 args[0] = this.textBox1.Text;
    6 args[1] = this.textBox2.Text;
    7
    8 object result = InvokeWebService.WebServiceHelper.InvokeWebService(url, "HelloWorld", args);
    9 this.textBox3.Text = result.ToString();
    10
    11 }

    调用Web Service后的运行结果如下:

    总结:本例主要用到了以下四个知识点:

     (1)WebService相关知识 ;

    Ø(2)代码文档对象模型CodeDom的使用 ;
    Ø(3)编程使用C#编译器 ;
    Ø(4)反射;
  • 相关阅读:
    微服务之SpringCloud基础
    java 多线程学习
    tomcat性能优化
    js模块化规范
    jsonp及cors
    es6之各种数据类型的扩展
    es6之Promise
    es6之Set和Map
    es6之Generator
    es6之Iterator
  • 原文地址:https://www.cnblogs.com/blueskybcl/p/1752320.html
Copyright © 2011-2022 走看看