通常我们在程序中需要调用WebService时,都是通过“添加Web引用”,让VS.NET环境来为我们生成服务代理,然后调用对应的Web服务。这样是使工作简单了,但是却和提供Web服务的URL、方法名、参数绑定在一起了,这是VS.NET自动为我们生成Web服务代理的限制。如果哪一天发布Web服务的URL改变了,则我们需要重新让VS.NET生成代理,并重新编译。在某些情况下,这可能是不能忍受的,我们需要动态调用WebService的能力。比如我们可以把Web服务的URL保存在配置文件中,这样,当服务URL改变时,只需要修改配置文件就可以了。
    说了这么多,实际上我们要实现这样的功能:

public static object InvokeWebService(string url,  string methodname, object[] args)

其中,url是Web服务的地址,methodname是要调用服务方法名,args是要调用Web服务所需的参数,返回值就是web服务返回的结果了。

要实现这样的功能,你需要这几个方面的技能:反射、CodeDom、编程使用C#编译器、WebService。在了解这些知识后,就可以容易的实现web服务的动态调用了:

    #region InvokeWebService
//动态调用web服务
public static object InvokeWebService(string url, string methodname, object[] args)
{
return WebServiceHelper.InvokeWebService(url ,null ,methodname ,args) ;
} public static object InvokeWebService(string url, string classname, string methodname, object[] args)
{
string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling" ;
if((classname == null) ||(classname == ""))
{
classname = WebServiceHelper.GetWsClassName(url) ;
} 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); //生成客户端代理类代码
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());
} //生成代理实例,并调用方法
System.Reflection.Assembly assembly = cr.CompiledAssembly;
Type t = assembly.GetType(@namespace+"."+classname,true,true);
object obj = Activator.CreateInstance(t);
System.Reflection.MethodInfo mi = t.GetMethod(methodname); return mi.Invoke(obj,args);
}
catch(Exception ex)
{
throw new Exception(ex.InnerException.Message,new Exception(ex.InnerException.StackTrace));
}
} private static string GetWsClassName(string wsUrl)
{
string[] parts = wsUrl.Split('/') ;
string[] pps = parts[parts.Length-].Split('.') ; return pps[] ;
}
#endregion

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

  string url = "http://www.webservicex.net/globalweather.asmx" ;
string[] args = new string[] ;
args[] = this.textBox_CityName.Text ;
args[] = "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)要漂亮的多。

动态调用web服务的更多相关文章

  1. 动态调用web服务 --WSHelper.cs

    using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Net;us ...

  2. 使用ASP.NET AJAX 从脚本中调用Web 服务的应用方法

    技能点:通过编写WebService,在页面js中调用WebService来进行数据查询. 网站开发,有些时候需要使用js在页面动态生成一些内容,但还有些数据要通过查询数据库才能获取的. 但由于诸如主 ...

  3. Android调用Web服务

    现在大部分应用程序都把业务逻辑处理,数据调用等功能封装成了服务的形式,应用程序只需要调用这些web服务就好了,在这里就不赘述web服务的优点了.本文总结如何在android中调用Web服务,通过传递基 ...

  4. 动态调用WCF服务

    动态调用WCF服务,只需要提供*.svc地址, 1:命名空间: using System.ServiceModel.Channels;using System.ServiceModel; 2:创建访问 ...

  5. 在 SQL Server 的存储过程中调用 Web 服务

    介绍 一个老朋友计划开发一个应用,基于 .NET 和 Socket,但需要在存储过程中调用 Web 服务. 在这篇文章中我们将分享这个应用的经验,讲述如何在存储过程中调用 Web 服务,并传递参数. ...

  6. mvc路由引起异步调用web服务的问题

    从一篇blog得知使用脚本可以异步调用Web服务,觉得很新鲜,因为自己很少用到Web服务,所以决定写一写看看什么效果. 首先在UI项目(我使用的是MVC4.0)里创建一个Web服务. 添加Web服务后 ...

  7. 25.C# 异步调用Web服务

    1.创建Web服务 1.1VS新建ASP.Net空Web应用程序 1.2添加Web服务新建项 1.3添加GetWeather方法和相关类 using System; using System.Coll ...

  8. 采用动态代理方式调用WEB服务(转载+整理)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  9. 记录:Web无引用无配置方式动态调用WCF服务

    这几年一直用WebApi较多,最近项目中有个需求比较适合使用WCF,以前也用过JQuery直接调用Wcf的,但是说实话真的忘了… 所以这次解决完还是花几分钟记录一下 WCF服务端:宿主在现有Win服务 ...

随机推荐

  1. duxcms SQL Injection In /admin/module/loginMod.class.php

    目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 duxcms是一款采用PHP开发,基于HMVC规则开发适合中小企业.公司.新闻.个 ...

  2. C++ essentials 之 union

    Extraction from The C++ Programming Language 4th. edition, Bjarne Stroustrup [8.1] A struct is a seq ...

  3. 安装PhantomJS

    安装步骤 # 安装依赖软件 yum -y install wget fontconfig # 下载PhantomJS wget -P /tmp/ https://bitbucket.org/ariya ...

  4. tail 命令 查看Tomcat目录下日志的最后几行的方法

    工作中需要查看日志信息,进行排错,但是面对上万行的错误日志,从头开始往后看,比较浪费时间,所有使用tail命令会节省不少时间. 1.命令   tail  - n  opt/tomcat/logs/ca ...

  5. matlab和C/C++混合编程--调用opencv

    最近的我们已经将整个项目搭起来了,项目比较复杂.由于我们做的是检索系统,所以我们用asp.net(c#)做了网页,但是算法的实现是在matlab下,所以我们不得不用matlab生成动态链接库dll,然 ...

  6. C#中int,string,char[],char的转换(待续)

    //char[]转string string mm = "woshicainiao"; char[] ss = mm.ToCharArray(); string AA = new ...

  7. JQuery------Select标签的各种使用方法

    optioin属性(value) <option value='>Hello</option> option的点击事件 <select class="s-one ...

  8. PHP中“简单工厂模式”实例讲解

    原创文章,转载请注明出处:http://www.cnblogs.com/hongfei/archive/2012/07/07/2580776.html 简单工厂模式:①抽象基类:类中定义抽象一些方法, ...

  9. c#根据公式进行自动计算 四个5加减乘除=4

        想不出来就采用枚举法吧,代码写起来还是很简单的,当然代码写的不怎么样,也不考虑设计效率等等问题了,理论上这种类型的都可以这么拼出来,比较初级的做法,但轻松解决问题.注意Calculate(st ...

  10. php ceil() 函数向上舍入为最接近的整数。

    代码: <?php echo(ceil(0.60); echo(ceil(0.40); echo(ceil(); echo(ceil(5.1); echo(ceil(-5.1); echo(ce ...