在前两讲里,我已经向大家演示了如何使用WebService、同步,异步调用WebService,而在实际开发过程中,可能会有多个WebService接口供你选择,而在程序执行过程中才决定使用哪一个WebService的情况,而以前的情况往往是添加指定的web引用调用WebService,而这一讲中,会讲述动态调用WebService。
首先贴出整个架构的示意图(图片来自浪曦)
首先实现ServiceHelper类,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
namespace InvokeWebService
{
public static class WebServiceHelper
{
/// <summary>
/// 动态调用WebService
/// </summary>
/// <p@R_502_6460@m name="url">WebService地址</p@R_502_6460@m>
/// <p@R_502_6460@m name="methodname">WebService方法名</p@R_502_6460@m>
/// <p@R_502_6460@m name="args">参数列表</p@R_502_6460@m>
/// <returns>返回object</returns>
public static object InvokeWebService(string url,string methodname,object[] args)
{
return InvokeWebService(url,null,methodname,args);
}
/// <summary>
/// 动态调用WebService
/// </summary>
/// <p@R_502_6460@m name="url">WebService地址</p@R_502_6460@m>
/// <p@R_502_6460@m name="classname">类名</p@R_502_6460@m>
/// <p@R_502_6460@m name="methodname">WebService方法名</p@R_502_6460@m>
/// <p@R_502_6460@m name="args">参数列表</p@R_502_6460@m>
/// <returns>返回object</returns>
public static object InvokeWebService(string url,string classname,object[] args)
{
string @namespace = "ServiceBase.WebService.DynamicWebLoad";
if (string.IsNullOrEmpty(classname))
{
classname = WebServiceHelper.GetClassName(url);
}
//获取服务描述语言(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();
//设定编译器的参数
CompilerP@R_502_6460@meters cplist = new CompilerP@R_502_6460@meters();
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 StringBuilder();
foreach (CompilerError ce in cr.Errors)
{
sb.Append(ce.ToString() + 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);
}
/// <summary>
/// 得到URL中的WebService名称
/// </summary>
/// <p@R_502_6460@m name="url">URL地址</p@R_502_6460@m>
/// <returns>如http://wwww.baidu.com/service.asmx 则返回service</returns>
private static string GetClassName(string url)
{
string[] parts = url.Split('/');
string[] pps = parts[parts.Length - 1].Split('.');
return pps[0];
}
}
}
然后,我们可以新建1,2个WebService,看看是如何动态调用的:
private void button1_Click(object sender,EventArgs e) { string url = "http://localhost:2697/Service1.asmx"; //WebService1
object b = InvokeWebService.WebServiceHelper.InvokeWebService(url,"HelloWorld",null); MessageBox.Show(b.ToString()); }
现在,整个项目中,没有像以往一样使用添加web引用来调用WebService,而是把WebService的调用地址,写在程序里面,结合业务逻辑可以动态调用wbeservice
ps:项目我是按着浪曦的视频自己写的,WebServiceHelper类里面有几个作用都不是很懂,这里纯属留下一份代码以作记录。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。