在C#程序中,若要调用WebService,一般是采用"添加Web引用"的方式来实现的。但如果此WebService的URL是在程序运行过程中才能获得的,那怎么办呢?那就必须是"动态"调用这个WebService了。
网上有不少关于这方面的例子,总结了一下,主要有两种:(1)每次都动态调用,(2)将WebService生成为一个本地的DLL,生成客户端的实例。
第一种方法:
我把它放到一个叫WebServiceHelper.cs的类里面了。
- /// <summary>
- /// 动态调用WebService
- /// </summary>
- /// <param name="url">WebService地址</param>
- /// <param name="classname">类名</param>
- /// <param name="methodname">方法名(模块名)</param>
- /// <param name="args">参数列表</param>
- /// <returns>object</returns>
- public static object InvokeWebService(string url, string classname,153); background-color:inherit; font-weight:bold">string methodname,153); background-color:inherit; font-weight:bold">object[] args)
- {
- string @namespace = "ServiceBase.WebService.DynamicWebLoad";
- if (classname == null || 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();
- //设定编译器的参数
- 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,153); background-color:inherit; font-weight:bold">if (true == cr.Errors.HasErrors)
- {
- System.Text.StringBuilder sb = new StringBuilder();
- foreach (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,153); background-color:inherit; font-weight:bold">true,153); background-color:inherit; font-weight:bold">true);
- object obj = Activator.CreateInstance(t);
- System.Reflection.MethodInfo mi = t.getmethod(methodname);
- return mi.Invoke(obj, args);
- }
- private string GetClassName(string url)
- string[] parts = url.Split('/');
- string[] pps = parts[parts.Length - 1].Split('.');
- return pps[0];
- }
举个使用它的例子:
copy