zoukankan      html  css  js  c++  java
  • 动态调用Web服务

    事实上,我们在程序过程中,经常会有意无意地使用到Web服务。而且经常性地处于协作工作状态下,如果是同部门,同公司还好。直接添加WEB引用即可。但如果是处于不同公司或者不同时间段整合的项目的话,我们会经常在不知道Web服务具体实现下来使用Web服务。并且也很有可能出于某些商业原因的情况下,Web服务的地址也会经常更换。

    Web服务其实并不难理解。和普通的DLL一样,只要添加引用,我们就可以和普通的DLL一样,调用使用了。但要是碰到不能使用添加WEB引用的情况下,如何调用?或者说像上面讲的一样,经常更换WEB服务地址的情况下如何调用?总不能更换一次就重新编译一次吧?

    前几天就碰到了这种情况,在百度上搜了一下,才知道有一个动态调用WEB服务的概念,真是大长见识啊。赶快收集了一些相关资料,整理了一下。

    现贴出来放在这里,供大家学习交流。

     

    //-----代码开始

    using System;

    using System.IO;

    using System.Configuration;

    using System.CodeDom;

    using System.CodeDom.Compiler;

    using System.Net;

    using System.Web.Services;

    using System.Web.Services.Description;

    using Microsoft.CSharp;

    using System.Collections;

    using System.Reflection;

     

    namespace WuYou.NetSignUp

    {

         /// <summary>

         /// WebServiceHelper 的摘要说明。

         /// </summary>

         public class WebServiceHelper

         {

             private string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling" ;        //命名空间

             private Assembly assembly = null;    //程序集;

             private string classname = string.Empty;  //类名称;

             private Type t;             //表示类型;

             private object obj = null;       //表示实例;

             private Boolean isSuccess = false;   //是否创建实例成功;

     

     

             public WebServiceHelper(string Url,string classname)

             {

                  if(classname == null || classname == string.Empty)

                       this.classname = GetWsClassName(Url);

                  else

                       this.classname = classname;

     

                  try

                  {

                       //获取WSDL

                       WebClient wc                   = new WebClient();

                       Stream stream                  = wc.OpenRead(Url+"?WSDL");

                       ServiceDescription sd          = ServiceDescription.Read(stream);

                       ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();

                       sdi.AddServiceDescription(sd,"","");

                       CodeNamespace cn                = new CodeNamespace(@namespace);

                       stream.Close();

     

                       //生成客户端代理类代码

                       CodeCompileUnit ccu             = new CodeCompileUnit();

                       ccu.Namespaces.Add(cn);

                       sdi.Import(cn ,ccu);

                       CSharpCodeProvider csc          = new CSharpCodeProvider();

                       ICodeCompiler icc               = csc.CreateCompiler();

                   

                       //设定编译参数

                       CompilerParameters cplist       = new CompilerParameters();

                       cplist.GenerateExecutable       = false;

                       cplist.GenerateInMemory         = true;

                       cplist.ReferencedAssemblies.Add("System.dll");

                       cplist.ReferencedAssemblies.Add("System.XML.dll");

                       cplist.ReferencedAssemblies.Add("System.Web.Services.dll");

                       cplist.ReferencedAssemblies.Add("System.Data.dll");

     

                       //编译代理类

                       CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);

                      

                       if(true == cr.Errors.HasErrors)

                       {

                           System.Text.StringBuilder sb = new System.Text.StringBuilder();

                           foreach(System.CodeDom.Compiler.CompilerError ce in cr.Errors)

                           {

                                sb.Append(ce.ToString());

                                sb.Append(System.Environment.NewLine);

                           }

                           throw new Exception(sb.ToString());

                       }                         

      

                       assembly = cr.CompiledAssembly;

                  }

                  catch (System.Exception ex)

                  {

                       throw new Exception(ex.InnerException.Message,new Exception(ex.InnerException.StackTrace));

                  }

             }

     

             private Boolean CreateInstance()

             {

                  try

                  {

                       t = assembly.GetType(@namespace+"."+classname,true,true);

                       obj = Activator.CreateInstance(t);

                       isSuccess = true;

                  }

                  catch (System.Exception e)

                  {

                       throw new Exception(e.Message);

                  }

                  return isSuccess;

             }

     

             public object InvokeWebService(string methodanme,object[] parms)

             {

     

                  if(!isSuccess)

                  {

                       CreateInstance();

                  }

     

                  try

                  {            

                       System.Reflection.MethodInfo mi = t.GetMethod(methodanme);

     

                       return mi.Invoke(obj,parms);

               

                  }

                  catch (System.Exception ex)

                  {

                       throw new Exception(ex.InnerException.Message,new Exception(ex.InnerException.StackTrace));

                  }

     

             }

     

             private string GetWsClassName(string wsUrl)

             {

                  string[] parts = wsUrl.Split('/') ;

                  string[] pps   = parts[parts.Length-1].Split('.') ;

     

                  return pps[0] ;

             }

         }

    }

     

    //---代码结束

     

    使用过程也很简单,在实例化过程中,将WEB服务目前的WEB地址和类名传入即可。如果类名没有公开,默认情况下自动获取(即WEB服务页面名称为类名)。在第一次调用服务时自己创建实例,尔后,将自己检测是否已创建实例。即不用重复编译代码和创建实例。

     

    以上代码是根据网上收集整理而来,并非本人原创,以此说明。原作者不详。

  • 相关阅读:
    Linux03__管理
    Linux02__常用命令
    Linux01__系统安装
    爬虫性能相关
    【转载】资源整合
    Continuous integration
    行业巨头的云计算冷数据存储应用和比较 2016-07-15
    win7中使用docker ——配置阿里云容器加速
    layui treeSelect插件的使用
    springboot 拦截器设置
  • 原文地址:https://www.cnblogs.com/sxlfybb/p/441477.html
Copyright © 2011-2022 走看看