工作中用到一个执行一个远程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         }
View Code