记一次动态调用WebService
这次的使用参考博客园中的ID是 生命不息,折腾不止 http://www.cnblogs.com/leolion/p/4757320.html ,感谢分享
博客园让自己慢慢的成长,少不了这些无私奉献的大牛,很是感谢。
动态调用的具体步骤为:
1)从目标 URL 下载 WSDL 数据;
2)使用 ServiceDescription 创建和格式化 WSDL 文档文件;
3)使用 ServiceDescriptionImporter 创建客户端代理类;
4)使用 CodeDom 动态创建客户端代理类程序集;
5)利用反射调用相关 WebService 方法。
开始咯
Web.config中的配置,里边的代理类名称好像必须的和WebSevice中的服务名称一样。
<appSettings> <!--WebService地址--> <add key="WebServiceUrl" value="http://localhost:3933/WebService/InterfaceService.asmx" /> <!--WebService输出dll文件名称--> <add key="OutputDllFilename" value="TestWebService.dll" /> <!--WebService代理类名称--> <add key="ProxyClassName" value="InterfaceService" /> </appSettings>
创建一个枚举类,把需要映射WebService的方法名称放进去,调用方法的时候用起来方便
1 namespace WebConnWebService 2 { 3 /// <summary> 4 /// 方法枚举 5 /// </summary> 6 public enum EMethod 7 { 8 HelloWorld, 9 CancelOrder, 10 GetAllProductInfo, 11 GetOrderInfo , 12 GetProductInfo , 13 OrderSubmit, 14 QueryOrderDetails 15 } 16 }
新建类WSHelper.cs,代码如下,精髓
1 public class WSHelper 2 {/// <summary> 3 /// 输出的dll文件名称 4 /// </summary> 5 private static string m_OutputDllFilename; 6 7 /// <summary> 8 /// WebService代理类名称 9 /// </summary> 10 private static string m_ProxyClassName; 11 12 /// <summary> 13 /// WebService代理类实例 14 /// </summary> 15 private static object m_ObjInvoke; 16 17 /// <summary> 18 /// 接口方法字典 19 /// </summary> 20 private static Dictionary<EMethod, MethodInfo> m_MethodDic = new Dictionary<EMethod, MethodInfo>(); 21 22 /// <summary> 23 /// 创建WebService,生成客户端代理程序集文件 24 /// </summary> 25 /// <param name="error">错误信息</param> 26 /// <returns>返回:true或false</returns> 27 public static bool CreateWebService(out string error) 28 { 29 try 30 { 31 error = string.Empty; 32 m_OutputDllFilename = ConfigurationManager.AppSettings["OutputDllFilename"]; 33 m_ProxyClassName = ConfigurationManager.AppSettings["ProxyClassName"]; 34 string webServiceUrl = ConfigurationManager.AppSettings["WebServiceUrl"]; 35 webServiceUrl += "?WSDL"; 36 37 // 如果程序集已存在,直接使用 38 if (File.Exists(Path.Combine(Environment.CurrentDirectory, m_OutputDllFilename))) 39 { 40 BuildMethods(); 41 return true; 42 } 43 44 //使用 WebClient 下载 WSDL 信息。 45 WebClient web = new WebClient(); 46 Stream stream = web.OpenRead(webServiceUrl); 47 48 //创建和格式化 WSDL 文档。 49 if (stream != null) 50 { 51 // 格式化WSDL 52 ServiceDescription description = ServiceDescription.Read(stream); 53 54 // 创建客户端代理类。 55 ServiceDescriptionImporter importer = new ServiceDescriptionImporter 56 { 57 ProtocolName = "Soap", 58 Style = ServiceDescriptionImportStyle.Client, 59 CodeGenerationOptions = 60 CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync 61 }; 62 63 // 添加 WSDL 文档。 64 importer.AddServiceDescription(description, null, null); 65 66 //使用 CodeDom 编译客户端代理类。 67 CodeNamespace nmspace = new CodeNamespace(); 68 CodeCompileUnit unit = new CodeCompileUnit(); 69 unit.Namespaces.Add(nmspace); 70 71 ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit); 72 CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); 73 74 CompilerParameters parameter = new CompilerParameters 75 { 76 GenerateExecutable = false, 77 // 指定输出dll文件名。 78 OutputAssembly = m_OutputDllFilename 79 }; 80 81 parameter.ReferencedAssemblies.Add("System.dll"); 82 parameter.ReferencedAssemblies.Add("System.XML.dll"); 83 parameter.ReferencedAssemblies.Add("System.Web.Services.dll"); 84 parameter.ReferencedAssemblies.Add("System.Data.dll"); 85 86 // 编译输出程序集 87 CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit); 88 89 // 使用 Reflection 调用 WebService。 90 if (!result.Errors.HasErrors) 91 { 92 BuildMethods(); 93 return true; 94 } 95 else 96 { 97 error = "反射生成dll文件时异常"; 98 } 99 stream.Close(); 100 stream.Dispose(); 101 } 102 else 103 { 104 error = "打开WebServiceUrl失败"; 105 } 106 } 107 catch (Exception ex) 108 { 109 error = ex.Message; 110 } 111 return false; 112 } 113 114 /// <summary> 115 /// 反射构建Methods 116 /// </summary> 117 private static void BuildMethods() 118 { 119 Assembly asm = Assembly.LoadFrom(m_OutputDllFilename); 120 //var types = asm.GetTypes(); 121 Type asmType = asm.GetType(m_ProxyClassName); 122 m_ObjInvoke = Activator.CreateInstance(asmType); 123 124 //var methods = asmType.GetMethods(); 125 var methods = Enum.GetNames(typeof(EMethod)).ToList(); 126 foreach (var item in methods) 127 { 128 var methodInfo = asmType.GetMethod(item); 129 if (methodInfo != null) 130 { 131 var method = (EMethod)Enum.Parse(typeof(EMethod), item); 132 if (!m_MethodDic.ContainsKey(method)) 133 { 134 m_MethodDic.Add(method, methodInfo); 135 } 136 } 137 } 138 } 139 140 /// <summary> 141 /// 获取请求响应 142 /// </summary> 143 /// <param name="method">方法</param> 144 /// <param name="para">参数</param> 145 /// <returns>返回:Json串</returns> 146 public static string GetResponseString(EMethod method, params object[] para) 147 { 148 string result = null; 149 if (m_MethodDic.ContainsKey(method)) 150 { 151 var temp = m_MethodDic[method].Invoke(m_ObjInvoke, para); 152 if (temp != null) 153 { 154 result = temp.ToString(); 155 } 156 } 157 return result; 158 } 159 }
好了接下来就是调用,简单的测试一下了
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 string error; 4 bool succ = WSHelper.CreateWebService(out error);//先下载wsdl到本地如果本地已下载直接调用本地已下载好的dll,在把方法放到内存中以便调用 5 // SOAP 请求响应方式 6 //TextBox1.Text = WSHelper.GetResponseString(EMethod.Add, Convert.ToInt32(TextBox1.Text), Convert.ToInt32(TextBox2.Text)); 7 TextBox1.Text = WSHelper.GetResponseString(EMethod.HelloWorld); 8 }
前台显示