博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

动态调用web服务

Posted on 2008-10-19 16:03  codingsilence  阅读(250)  评论(0编辑  收藏  举报

 

 

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

调用示例

 

上面的注释已经很好的说明了各代码段的功能,下面给个例子看看,这个例子是通过访问http://www.webservicex.net/globalweather.asmx 服务来获取各大城市的天气状况。

            string url = "http://www.webservicex.net/globalweather.asmx" ;
            
string[] args = new string[2] ;
            args[
0= this.textBox_CityName.Text ;
            args[
1= "China" ;
            
object result = WebServiceHelper.InvokeWebService(url ,"GetWeather" ,args) ;
            
this.label_Result.Text = result.ToString() ;


    上述的例子中,调用web服务使用了两个参数,第一个是城市的名字,第二个是国家的名字,Web服务返回的是XML文档,可以从其中解析出温度、风力等天气情况。
    
    最后说一下,C#虽然仍属于静态语言之列,但是其动态能力也是很强大的,不信,你可以看看Spring.net的AOP实现,这种“无侵入”的AOP实现比通常的.NET声明式AOP实现(一般是通过AOP Attribute)要漂亮的多。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string url = "http://localhost/InvokeService/Service1.asmx";
            string[] args = new string[2];
            args[0] = this.textBox1.Text;
            args[1] = this.textBox2.Text;

            object result = InvokeWebService.WebServiceHelper.InvokeWebService(url, "HelloWorld", args);
            this.textBox3.Text = result.ToString();

        }
    }
}

方法二:

  1. 我也写了一个,可以调用,   没发现问题,   如下:   
  2.                 const   string   DefaultUrl   =   "http://192.168.60.27/ServiceDS/Service.asmx?wsdl";   
  3.                   static   Program   instance   =   new   Program();   
  4.     
  5.                   static   void   Main(string[]   args)   
  6.                   {   
  7.                           instance.InvokeMethod();   
  8.                           Console.ReadLine();   
  9.                   }   
  10.     
  11.                   void   InvokeMethod()   
  12.                   {   
  13.                           Assembly   proxyAssembly   =   CreateWSProxy(DefaultUrl);   
  14.                           Type   proxyType   =   proxyAssembly.GetType("WebServiceProxy.Service");                       
  15.                           MethodInfo   mi   =   proxyType.GetMethod("xxxMethod");   
  16.                           PropertyInfo   pi   =   proxyType.GetProperty("Credentials");   
  17.                           object   proxy   =   Activator.CreateInstance(proxyType);   
  18.                           pi.SetValue(proxy,   CredentialCache.DefaultCredentials,   new   object[0]);   
  19.                           Console.WriteLine(mi.Invoke(proxy,   new   object[]   {   "xxx"   }).ToString());   
  20.                   }   
  21.     
  22.                   Assembly   CreateWSProxy(string   url)   
  23.                   {   
  24.                           if   (String.IsNullOrEmpty(url))   
  25.                                   return   null;   
  26.     
  27.                           ServiceDescription   wsdl   =   GetWsdl(url);   
  28.                           CodeNamespace   cns   =   new   CodeNamespace("WebServiceProxy");   
  29.                           ServiceDescriptionImporter   sdi   =   new   ServiceDescriptionImporter();   
  30.                           sdi.AddServiceDescription(wsdl,   null,   null);   
  31.                           sdi.ProtocolName   =   "Soap";   
  32.                           sdi.Import(cns,   null);   
  33.     
  34.                           CSharpCodeProvider   cp   =   new   CSharpCodeProvider();   
  35.                           StringBuilder   sb   =   new   StringBuilder();   
  36.                           StringWriter   sw   =   new   StringWriter(sb);   
  37.                           cp.GenerateCodeFromNamespace(cns,   sw,   null);   
  38.                           string   src   =   sb.ToString();   
  39.                           sw.Close();   
  40.                           Console.WriteLine(src);   
  41.     
  42.                           CompilerParameters   cmp   =   new   CompilerParameters();   
  43.                           cmp.ReferencedAssemblies.Add("System.dll");   
  44.                           cmp.ReferencedAssemblies.Add("System.Xml.dll");   
  45.                           cmp.ReferencedAssemblies.Add("System.Web.Services.dll");   
  46.                           cmp.GenerateExecutable   =   false;   
  47.                           cmp.GenerateInMemory   =   true;   
  48.                           cmp.IncludeDebugInformation   =   false;   
  49.     
  50.                           CompilerResults   cr   =   cp.CompileAssemblyFromSource(cmp,   src);   
  51.     
  52.                           if   (cr.Errors.Count   >   0)   
  53.                                   throw   new   Exception(string.Format("Build   failed:   {0}   errors",   
  54.                                           cr.Errors.Count));   
  55.                           return   cr.CompiledAssembly;   
  56.                   }   
  57.     
  58.                   ServiceDescription   GetWsdl(string   url)   
  59.                   {   
  60.                           WebRequest   wreq   =   WebRequest.Create(url);   
  61.                           wreq.Credentials   =   CredentialCache.DefaultCredentials;   
  62.                           WebResponse   resp   =   wreq.GetResponse();   
  63.                           Stream   stream   =   resp.GetResponseStream();   
  64.                           StreamReader   sr   =   new   StreamReader(stream,   System.Text.Encoding.UTF8);   
  65.                           string   desc   =   sr.ReadToEnd();   
  66.                           XmlTextReader   xtr   =   new   XmlTextReader(new   StringReader(desc));   
  67.     
  68.                           ServiceDescription   wsdl   =   ServiceDescription.Read(xtr);   
  69.                           xtr.Close();   
  70.                           sr.Close();   
  71.                           stream.Close();   
  72.                           resp.Close();   
  73.                           return   wsdl;   
  74.                   }