工作中用到一个执行一个远程webservices 为保障webservices 的运行,自己用窗体拖了一个小exe,便于查看,但这里面远程的方法不仅仅有返回值还带有 类似 ref out 这类返回参数,所以 查了下 MethodInfo 有关用法:
来自以为axdhxyzx的博客的点评:
1, 用Invoke方法时,参数列表成为了object数组,当传递数组进去,只是给这个方法提供参数,而out参数根本不需要外界提供值,而是往外界输出值。
2, 新的思维方法(即Invoke方法使用的思维)是:方法产生的输出值并没有存到object数组中使用的变量,而是存到了object数组中,ref参数则是提供参数和out参数的集合体,所以ref和out产生的新数据需要在object数组中提取,数组中使用的变量并不会因此改变值。
给我带来很多启发,以下是具体实现细节:
1 public XmlElement LoadData( ref int v_code,ref string v_msg) 2 { 3 try 4 { 5 WebClient client = new WebClient(); 6 //这个地址可以写在Config文件里面,这里取出来就行了 7 String url = this.txtAddress.Text + "?WSDL"; 8 Stream stream = client.OpenRead(url); 9 ServiceDescription description = ServiceDescription.Read(stream); 10 ServiceDescriptionImporter importer = new ServiceDescriptionImporter();//创建客户端代理代理类。 11 importer.ProtocolName = "Soap"; //指定访问协议。 12 importer.Style = ServiceDescriptionImportStyle.Client; //生成客户端代理。 13 importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync; 14 importer.AddServiceDescription(description, null, null); //添加WSDL文档。 15 CodeNamespace nmspace = new CodeNamespace(); //命名空间 16 nmspace.Name = "AirlineMeals"; 17 CodeCompileUnit unit = new CodeCompileUnit(); 18 unit.Namespaces.Add(nmspace); 19 ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit); 20 CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); 21 CompilerParameters parameter = new CompilerParameters(); 22 parameter.GenerateExecutable = false; 23 parameter.OutputAssembly = "svchostl.dll";//输出程序集的名称 24 parameter.ReferencedAssemblies.Add("System.dll"); 25 parameter.ReferencedAssemblies.Add("System.XML.dll"); 26 parameter.ReferencedAssemblies.Add("System.Web.Services.dll"); 27 parameter.ReferencedAssemblies.Add("System.Data.dll"); 28 CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit); 29 if (result.Errors.HasErrors) 30 { 31 // 显示编译错误信息 32 } 33 //加载前面生成的程序集 34 Assembly asm = Assembly.LoadFrom("svchostl.dll"); 35 Type t = asm.GetType("AirlineMeals" + "." + description.Services[0].Name); 36 object o = Activator.CreateInstance(t); 37 //GetPersons是服务端的方法名称,你想调用服务端的什么方法都可以在这里改,最好封装一下 38 MethodInfo method = t.GetMethod("IF01"); 39 //ParameterInfo[] pmp = method.GetParameters(); 40 //double code = 0; 41 object[] Args = new object[] { this.Dt_FilghtDate.Text, this.txtRkdh.Text.Trim(), this.txtFilghtNo.Text.Trim(), v_code, v_msg }; 42 // XmlElement xml = (XmlElement)method.Invoke(o, new object[] { this.Dt_FilghtDate.Text, this.txtRkdh.Text.Trim(), this.txtFilghtNo.Text.Trim(), v_code, v_msg }); 43 XmlElement xml = (XmlElement)method.Invoke(o, Args); 44 //注:method.Invoke(o, null)返回的是一个Object,如果你服务端返回的是DataSet, 45 //这里也是用(DataSet)method.Invoke(o, null)转一下就行了 46 v_code = int.Parse (Args[3].ToString()); 47 v_msg = Args[4].ToString(); 48 return xml; 49 //上面是根据WebService地址,模似生成一个代理类,如果你想看看生成的代码文件是什么样子, 50 //可以用以下代码保存下来,默认是保存在bin目录下面 51 //TextWriter writer = File.CreateText("MyTest.cs"); 52 //provider.GenerateCodeFromCompileUnit(unit, writer, null); 53 //writer.Flush(); 54 //writer.Close(); 55 //Console.ReadLine(); 56 } 57 catch (Exception ex) 58 { 59 MessageBox.Show(ex.Message); 60 return null; 61 } 62 }
浙公网安备 33010602011771号