1.大多数情况下,我们都是在VS里面通过添加Web引用的方式,在客户端自动生成客户端代理去调用WebService的,
有时候,服务器端的地址可能会经常变,这里就需要动态的调用WebService,
一种是服务没有变化只是IP地址变化了,这样我们只需要在获取客户端代理的时候,将其URL地址修改即可。
另一种可能服务参数等发生变化了,这样我们可以通过CodeDOMega,反射灯相关技术实现动态调用,步骤如下:
1.下载WSDL文档
2.创建ServiceDescription描述对象
3.创建服务客户端代理
4.编译客户端代理
5.反射调用服务方法。
这里创建一个测试用的WebService,里面有一个方法 SayHello().生成并发布,
源码如下:
WebService:

using System; using System.Data; using System.Web; using System.Collections; using System.Web.Services; using System.Web.Services.Protocols; using System.ComponentModel; namespace testInvokeWebSerivce { /// <summary> /// Service1 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ToolboxItem(false)] public class Service1 : System.Web.Services.WebService { [WebMethod] public string SayHello(string name) { return "Hello " + name; } } }
Client:

using System; using System.Collections.Generic; using System.Text; using System.Web; using System.Net; using System.IO; using System.Web.Services; using System.Web.Services.Description; using System.Xml.Serialization; using System.CodeDom; using System.CodeDom.Compiler; using System.Reflection; namespace Client { class Program { static void Main(string[] args) { Program pro = new Program(); pro.InvokeMethod("http://localhost/testInvokeWebService/TestSrv.asmx", "Service1", "SayHello", "阿牛哥"); } public void InvokeMethod(string uri, string serviceName, string methodName, string parameters) { //下载WSDL描述信息 WebClient web = new WebClient(); Stream stream = web.OpenRead(uri + @"?WSDL"); //创建ServiceDescription描述 ServiceDescription description = ServiceDescription.Read(stream); //创建客户端代理 ServiceDescriptionImporter import = new ServiceDescriptionImporter(); import.ProtocolName = "SOAP"; import.Style = ServiceDescriptionImportStyle.Client; //import.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;//这个是来自于 System.Xml.Serialization命名空间下 import.AddServiceDescription(description, null, null); //编译客户端 CodeNamespace ns = new CodeNamespace();//使用默认全局命名空间 CodeCompileUnit unit = new CodeCompileUnit(); unit.Namespaces.Add(ns);//少了这句不能获得类型了 ServiceDescriptionImportWarnings warnings = import.Import(ns, unit); CompilerParameters para = new CompilerParameters(); para.GenerateInMemory = true; para.GenerateExecutable = false; //这个地方注意引用的DLL,少一个都会出错的。。。我就是少了个System.XML.Dll para.ReferencedAssemblies.Add("System.dll"); para.ReferencedAssemblies.Add("System.XML.dll"); para.ReferencedAssemblies.Add("System.Data.dll"); para.ReferencedAssemblies.Add("System.Web.Services.dll"); //CodeDomProvider provider = CodeDomProvider.CreateProvider("C#"); CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); CompilerResults results = provider.CompileAssemblyFromDom(para, unit); if (!results.Errors.HasErrors) { Assembly ass = results.CompiledAssembly; Type[] sss = ass.GetTypes(); Type type = ass.GetType(serviceName); Object obj = Activator.CreateInstance(type, null); MethodInfo method = type.GetMethod(methodName); string ss = method.Invoke(obj, new string[] { parameters }).ToString(); Console.WriteLine(ss); } results.Errors.ToString(); } } }
效果图: