其中,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 - 1 ].Split( ' . ' ) ; return pps[ 0 ] ; } #endregion上面的注释已经很好的说明了各代码段的功能,下面给个例子看看,这个例子是通过访问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)要漂亮的多。
转载于:https://www.cnblogs.com/Jwin/archive/2009/01/07/1371253.html
相关资源:C#动态调用webservice服务