在本节课程中,将演示如何通过程序动态添加、调用、编译、执行WebService并返回结果。
WebService动态调用示意图
WebService相关知识
代码文档对象模型CodeDom的使用
编程使用C#编译器
反射
1.先建动态调用辅助类 WebServiceHelper.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.IO; 6 using System.Configuration; 7 using System.CodeDom; 8 using System.CodeDom.Compiler; 9 using System.Net; 10 using System.Web.Services; 11 using System.Web.Services.Description; 12 using Microsoft.CSharp; 13 14 15 namespace InvokeWebService 16 { 17 public static class WebServiceHelper 18 { 19 /// <summary> 20 /// 动态调用WebService 21 /// </summary> 22 /// <param name="Url">WebService地址</param> 23 /// <param name="methodname">WebService方法名(模块名)</param> 24 /// <param name="args">调用接口的参数列表</param> 25 /// <returns></returns> 26 public static object InvokeWebService(string Url,string methodname,object[] args) 27 { 28 return InvokeWebService(Url, null, methodname, args); 29 } 30 31 /// <summary> 32 /// 动态调用WebService 33 /// </summary> 34 /// <param name="Url">WebService地址</param> 35 /// <param name="className">类名</param> 36 /// <param name="methodname">WebService方法名</param> 37 /// <param name="args">调用接口的参数列表</param> 38 /// <returns></returns> 39 public static object InvokeWebService(string Url, string className, string methodname, object[] args) 40 { 41 string @namespace = "ServiceBase.WebSerice.DynamicWebLoad"; 42 if (className == null || className == "") 43 { 44 className = WebServiceHelper.GetClassName(Url); 45 } 46 //1.服务描述语言(WSDL) 47 WebClient wc = new WebClient(); 48 Stream stream = wc.OpenRead(Url + "?WSDL"); 49 ServiceDescription sd = ServiceDescription.Read(stream); 50 ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); 51 sdi.AddServiceDescription(sd, "", ""); 52 CodeNamespace cn = new CodeNamespace(@namespace); 53 54 //2.生成客户端代理类代码 55 CodeCompileUnit ccu = new CodeCompileUnit(); 56 ccu.Namespaces.Add(cn); 57 sdi.Import(cn, ccu); 58 CSharpCodeProvider csc = new CSharpCodeProvider(); 59 ICodeCompiler icc = csc.CreateCompiler(); 60 //3.设定编译器的参数 61 CompilerParameters cplist = new CompilerParameters(); 62 cplist.GenerateExecutable=false; 63 cplist.GenerateInMemory = true; 64 cplist.ReferencedAssemblies.Add("System.dll"); 65 cplist.ReferencedAssemblies.Add("System.XML.dll"); 66 cplist.ReferencedAssemblies.Add("System.Web.Services.dll"); 67 cplist.ReferencedAssemblies.Add("System.Data.dll"); 68 //4.变异代理类 69 CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu); 70 if (true==cr.Errors.HasErrors) 71 { 72 System.Text.StringBuilder sb = new StringBuilder(); 73 foreach (CompilerError ce in cr.Errors) 74 { 75 sb.Append(ce.ToString()); 76 sb.Append(System.Environment.NewLine); 77 } 78 throw new Exception(sb.ToString()); 79 } 80 //生成代理实例,并调用方法 81 System.Reflection.Assembly assembly = cr.CompiledAssembly; 82 Type t = assembly.GetType(@namespace + "." + className, true, true); 83 object obj = Activator.CreateInstance(t); 84 System.Reflection.MethodInfo mi = t.GetMethod(methodname); 85 return mi.Invoke(obj, args); 86 } 87 88 //获取类名 89 private static string GetClassName(string url) 90 { 91 string[] parts = url.Split('/'); 92 string[] pps = parts[parts.Length - 1].Split('.'); 93 return pps[0]; 94 } 95 } 96 }
2.建WebService, Service1.asmx
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Services; 6 7 namespace InvokeServices 8 { 9 /// <summary> 10 /// Service1 的摘要说明 11 /// </summary> 12 [WebService(Namespace = "http://tempuri.org/")] 13 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 14 [System.ComponentModel.ToolboxItem(false)] 15 // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。 16 // [System.Web.Script.Services.ScriptService] 17 public class Service1 : System.Web.Services.WebService 18 { 19 20 [WebMethod] 21 public string HelloWorld(string Temp1,string Temp2) 22 { 23 return string.Format("参数1:{0},参数2:{1}", Temp1, Temp2); 24 } 25 } 26 }
3.建应用程序
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 10 namespace Test 11 { 12 public partial class Form1 : Form 13 { 14 public Form1() 15 { 16 InitializeComponent(); 17 } 18 19 private void button1_Click(object sender, EventArgs e) 20 { 21 string url = "http://localhost:4547/Service1.asmx"; 22 string[] args = new string[2]; 23 args[0] = this.textBox1.Text; 24 args[1] = this.textBox2.Text; 25 object result = InvokeWebService.WebServiceHelper.InvokeWebService(url, "HelloWorld", args); 26 27 this.textBox3.Text = result.ToString(); 28 } 29 } 30 }