动态调用Web Service

由于Web Service 的地址在编写代码是不能确定或者地址经常变化。所以不能通过简单的添加WEB 引用来实现。

需要编写代码根据输入的地址动态编译代理类,通过反射动态生成代理类,动态调用方法。

调用代码:

代码
1 protected void btnCall_Click(object sender, EventArgs e)
2 {
3 string url = "http://localhost/OA_WebService/WebService/DyDataList.asmx";
4 string methodName = "GetBookList";
5 object[] args = null;
6 string str = WebServiceHelper.InvokeMethod<string>(url, methodName, args);
7 Response.Write(str);
8 }

 

WebServiceHelper类代码

 

代码
1 using System;
2  using System.Linq;
3  using System.Web;
4  using System.Net;
5 using System.IO;
6 using System.CodeDom;
7 using Microsoft.CSharp;
8 using System.Reflection;
9 using System.CodeDom.Compiler;
10 using System.Collections.Generic;
11 using System.Web.Services.Protocols;
12 using System.Web.Services.Description;
13
14 /// <summary>
15 /// 动态调用Webservice方法
16 /// </summary>
17 public class WebServiceHelper
18 {
19 /// <summary>
20 /// 动态调用方法
21 /// </summary>
22 /// <typeparam name="T">方法返回值的类型</typeparam>
23 /// <typeparam name="soapT">SoapHeader的具体类型</typeparam>
24 /// <param name="soapObject">SoapHeader实例</param>
25 /// <param name="url">网址</param>
26 /// <param name="methodName">方法名</param>
27 /// <param name="args">参数</param>
28 /// <returns>返回调用结果</returns>
29 //public static T InvokeMethod<T, soapT>(soapT soapObject, string url, string methodName, object[] args)
30 //{
31 // T result = default(T);
32 // Type t = GetType(url, GetWsClassName(url));
33
34 // try
35 // {
36 // object obj = CreateInstance(t);
37 // SetProperty(obj, soapObject, t, "AuthHeaderValue");
38 // result = InvokeMethod<T>(obj, t, methodName, args);
39 // }
40 // catch (Exception ex)
41 // {
42 // throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace));
43 // }
44
45 // return result;
46 //}
47
48 /// <summary>
49 /// 动态调用方法
50 /// </summary>
51 /// <typeparam name="T">方法返回值的类型</typeparam>
52 /// <param name="url">网址</param>
53 /// <param name="methodName">方法名</param>
54 /// <param name="args">参数</param>
55 /// <returns>返回调用结果</returns>
56 public static T InvokeMethod<T>(string url, string methodName, object[] args)
57 {
58 //设置泛型类型的默认值
59 T result = default(T);
60 //获得类型
61 Type t = GetType(url, GetWsClassName(url));
62
63 try
64 {
65 //依据类型创建实例
66 object obj = CreateInstance(t);
67 //调用方法
68 result = InvokeMethod<T>(obj, t, methodName, args);
69 }
70 catch (Exception ex)
71 {
72 throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace));
73 }
74
75 return result;
76 }
77
78 /// <summary>
79 /// 动态调用方法
80 /// </summary>
81 /// <typeparam name="T">方法返回值的类型</typeparam>
82 /// <param name="InstanceObject">实例</param>
83 /// <param name="t">类的类型(Type)</param>
84 /// <param name="methodName">方法名</param>
85 /// <param name="args">参数</param>
86 /// <returns>返回调用结果</returns>
87 private static T InvokeMethod<T>(object InstanceObject, Type t, string methodName, object[] args)
88 {
89 T result = default(T);
90 //依据方法名获取方法信息
91 System.Reflection.MethodInfo mi = t.GetMethod(methodName);
92 //调用实例方法
93 result = (T)mi.Invoke(InstanceObject, args);
94 return result;
95 }
96
97 /// <summary>
98 /// 获取类型
99 /// </summary>
100 /// <param name="url">网址</param>
101 /// <param name="className">类型名称</param>
102 /// <returns>返回Type</returns>
103 private static Type GetType(string url, string className)
104 {
105 Type result = null;
106 string @namespace = "DoNet.Common.Utilities.Temp.WebService";
107 if(string.IsNullOrEmpty(className))
108 {
109 className = WebServiceHelper.GetWsClassName(url);
110 }
111 //获取WSDL
112 WebClient wc = new WebClient();
113 Stream stream = wc.OpenRead(url + "?WSDL");
114 ServiceDescription sd = ServiceDescription.Read(stream);
115 ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
116 sdi.AddServiceDescription(sd, "", "");
117 CodeNamespace np = new CodeNamespace(@namespace);
118
119 //生成客户端代理类代码
120 CodeCompileUnit ccu = new CodeCompileUnit();
121 ccu.Namespaces.Add(np);
122 sdi.Import(np, ccu);
123 CSharpCodeProvider csc = new CSharpCodeProvider();
124 //获取c#编译器的实例
125 ICodeCompiler icc = csc.CreateCompiler();
126
127 //设定编译参数
128 CompilerParameters cplist = new CompilerParameters();
129 cplist.GenerateExecutable = false;
130 cplist.GenerateInMemory = true;
131 cplist.ReferencedAssemblies.Add("System.dll");
132 cplist.ReferencedAssemblies.Add("System.XML.dll");
133 cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
134 cplist.ReferencedAssemblies.Add("System.Data.dll");
135
136 //编译代理类
137 CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
138 if (true == cr.Errors.HasErrors)
139 {
140 System.Text.StringBuilder sb = new System.Text.StringBuilder();
141 foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
142 {
143 sb.Append(ce.ToString());
144 sb.Append(System.Environment.NewLine);
145 }
146 throw new Exception(sb.ToString());
147 }
148
149 //生成代理实例,并调用方法
150 System.Reflection.Assembly assembly = cr.CompiledAssembly;
151 //反射获取类型
152 result = assembly.GetType(@namespace + "." + className, true, true);
153 return result;
154 }
155
156 /// <summary>
157 /// 依据类型创建实例
158 /// </summary>
159 /// <param name="t">类型(Type)</param>
160 /// <returns></returns>
161 private static object CreateInstance(Type t)
162 {
163 //获取类型的默认值
164 object result = null;
165 try
166 {
167 //创建实例类型
168 result = Activator.CreateInstance(t);
169 }
170 catch (Exception ex)
171 {
172 throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace));
173 }
174 return result;
175 }
176
177 /// <summary>
178 /// 给实例对象属性赋值
179 /// </summary>
180 /// <param name="InstanceObject">实例</param>
181 /// <param name="valueObj"></param>
182 /// <param name="t">类型(Type)</param>
183 /// <param name="propertyName">属性的名字</param>
184 private static void SetProperty(object InstanceObject,object valueObj,Type t, string propertyName)
185 {
186 //依据类型获得类型属性
187 System.Reflection.PropertyInfo pi = t.GetProperty(propertyName,BindingFlags.Public);
188 //给实例对象属性赋值
189 pi.SetValue(InstanceObject, valueObj, null);
190 }
191
192 /// <summary>
193 /// 获得类的名字
194 /// </summary>
195 /// <param name="url">网址</param>
196 /// <returns></returns>
197 private static string GetWsClassName(string url)
198 {
199 string result = string.Empty;
200 string[] parts = url.Split('/');
201 string fileName = parts[parts.Length - 1];
202 result = fileName.Split('.')[0];
203 return result;
204 }
205 }

 

posted @ 2010-07-16 09:59  希腊字符  阅读(545)  评论(0编辑  收藏  举报