动态调用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服务页面名称为类名)。在第一次调用服务时自己创建实例,尔后,将自己检测是否已创建实例。即不用重复编译代码和创建实例。

 

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

 

posted on 2006-07-03 13:58  房客  阅读(1514)  评论(1编辑  收藏  举报

导航