客户端代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.CodeDom.Compiler; using System.CodeDom; using System.Web.Services.Description; using System.Net; using System.IO; using System.Reflection; using Microsoft.CSharp; using System.Web.Configuration; using System.Xml.Serialization; using System.Xml; using System.Globalization; using System.Security.Permissions; namespace WebServiceTest { /// <summary> /// 动态调用WebService(支持SaopHeader) /// </summary> public class WebServiceHelper { /// <summary> /// 获取WebService的类名 /// </summary> /// <param name="wsUrl">WebService地址</param> /// <returns>返回WebService的类名</returns> private static string GetWsClassName(string wsUrl) { string[] parts = wsUrl.Split('/'); string[] pps = parts[parts.Length - 1].Split('.'); return pps[0]; } /// <summary> /// 调用WebService(不带SoapHeader) /// </summary> /// <param name="wsUrl">WebService地址</param> /// <param name="methodName">方法名称</param> /// <param name="args">参数列表</param> /// <returns>返回调用结果</returns> public static object InvokeWebService(string wsUrl, string methodName, object[] args) { return InvokeWebService(wsUrl, null, methodName, null, args); } /// <summary> /// 调用WebService(带SoapHeader) /// </summary> /// <param name="wsUrl">WebService地址</param> /// <param name="methodName">方法名称</param> /// <param name="soapHeader">SOAP头</param> /// <param name="args">参数列表</param> /// <returns>返回调用结果</returns> public static object InvokeWebService(string wsUrl, string methodName, SoapHeader soapHeader, object[] args) { return InvokeWebService(wsUrl, null, methodName, soapHeader, args); } /// <summary> /// 调用WebService /// </summary> /// <param name="wsUrl">WebService地址</param> /// <param name="className">类名</param> /// <param name="methodName">方法名称</param> /// <param name="soapHeader">SOAP头</param> /// <param name="args">参数列表</param> /// <returns>返回调用结果</returns> public static object InvokeWebService(string wsUrl, string className, string methodName, SoapHeader soapHeader, object[] args) { string @namespace = "IDPSystem.WebUI.WebService"; if ((className == null) || (className == "")) { className = GetWsClassName(wsUrl); } try { //获取WSDL WebClient wc = new WebClient(); Stream stream = wc.OpenRead(wsUrl + "?wsdl"); ServiceDescription sd = ServiceDescription.Read(stream); ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); sdi.Style = ServiceDescriptionImportStyle.Client;//生成客户端代理 sdi.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.None | System.Xml.Serialization.CodeGenerationOptions.GenerateOldAsync | System.Xml.Serialization.CodeGenerationOptions.GenerateOrder; sdi.ProtocolName = "Soap12"; sdi.AddServiceDescription(sd, "", ""); CodeNamespace cn = new CodeNamespace(@namespace); //生成客户端代理类代码 CodeCompileUnit ccu = new CodeCompileUnit(); ccu.Namespaces.Add(cn); sdi.Import(cn, ccu); //CSharpCodeProvider csc = new CSharpCodeProvider(); //ICodeCompiler icc = csc.CreateCompiler(); CodeDomProvider icc = CodeDomProvider.CreateProvider("CSharp"); // icc.GenerateCodeFromCompileUnit(ccu, Console.Out, new CodeGeneratorOptions());控制台输出 //设定编译参数 CompilerParameters cplist = new CompilerParameters(); cplist.GenerateExecutable = false; cplist.GenerateInMemory = true; cplist.OutputAssembly = @namespace + ".dll";//输出程序集的名称 cplist.ReferencedAssemblies.Add("System.dll"); cplist.ReferencedAssemblies.Add("System.XML.dll"); cplist.ReferencedAssemblies.Add("System.Web.Services.dll"); cplist.ReferencedAssemblies.Add("System.Data.dll"); cplist.ReferencedAssemblies.Add("System.ServiceModel.dll"); cplist.IncludeDebugInformation = true; //编译代理类 CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu); if (true == cr.Errors.HasErrors) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors) { sb.Append(ce.ToString()); sb.Append(System.Environment.NewLine); } throw new Exception(sb.ToString()); } //上面是根据WebService地址,模似生成一个代理类,如果你想看看生成的代码文件是什么样子,可以用以下代码保存下来,默认是保存在bin目录下面 TextWriter writer = File.CreateText("MyTest3.cs"); icc.GenerateCodeFromCompileUnit(ccu, writer, null); writer.Flush(); writer.Close(); //生成代理实例,并调用方法 System.Reflection.Assembly assembly = cr.CompiledAssembly; Type t = assembly.GetType(@namespace + "." + className, true, true); FieldInfo[] arry = t.GetFields(); FieldInfo client = null; // PropertyInfo pro = null; object clientkey = null; if (soapHeader != null) { //Soap头开始 client = t.GetField(soapHeader.ClassName + "Value"); //获取客户端验证对象 soap类 Type typeClient = assembly.GetType(@namespace + "." + soapHeader.ClassName); //为验证对象赋值 soap实例 clientkey = Activator.CreateInstance(typeClient); //遍历属性 foreach (KeyValuePair<string, object> property in soapHeader.Properties) { typeClient.GetField(property.Key).SetValue(clientkey, property.Value); // typeClient.GetProperty(property.Key).SetValue(clientkey, property.Value, null); } //Soap头结束 } //实例类型对象 object obj = Activator.CreateInstance(t); if (soapHeader != null) { //设置Soap头 client.SetValue(obj, clientkey); //pro.SetValue(obj, soapHeader, null); } ///作为object传递 List<object> objlist = new List<object>(); //代理类中staff 类型 Type ProxyStaff = assembly.GetType("IDPSystem.WebUI.WebService.Entity"); ///转为数组 Type ProxyStaffArray = ProxyStaff.MakeArrayType(1); SameWSEntity[] wsEntityList = (SameWSEntity[])args[(args.Length - 1)]; MethodInfo[] melist = ProxyStaffArray.GetMethods(BindingFlags.Public | BindingFlags.Instance); object array = ProxyStaffArray.InvokeMember("Set", BindingFlags.CreateInstance, null, wsEntityList, new object[] { wsEntityList.Length }); int i = 0;//array foreach (SameWSEntity staff in wsEntityList) { //创建代理类中staff的实例 object ProxyStaffEntity = Activator.CreateInstance(ProxyStaff); //遍历属性 foreach (FieldInfo item in ProxyStaff.GetFields()) { //遍历时候给属性赋值 object objVal = typeof(SameWSEntity).GetProperty(item.Name).GetValue(staff, null); item.SetValue(ProxyStaffEntity, objVal); } MethodInfo[] list = ProxyStaffArray.GetMethods(); ProxyStaffArray.GetMethod("SetValue", new Type[] { typeof(object), typeof(int) }).Invoke(array, new object[] { ProxyStaffEntity, i }); i++; //作为object数组 objlist.Add(ProxyStaffEntity); } //作为object数组 args[args.Length - 1] = array; // objlist.ToArray(); System.Reflection.MethodInfo mi = t.GetMethod(methodName); return mi.Invoke(obj, args); } catch (Exception ex) { throw new Exception(ex.ToString()); } } //慢慢理解吧,懒得写了 private static ErrorMessage ConvertToErrMsg(object obj) { ErrorMessage errMsg = new ErrorMessage(); List<ErrorMessage.ErrorData> errdata = new List<ErrorMessage.ErrorData>(); Type t = obj.GetType(); foreach (FieldInfo item in t.GetFields()) { Type tlist = item.FieldType; if (tlist.IsArray) { object[] val = item.GetValue(obj) as object[]; Type errType = val.GetType(); object array = errType.InvokeMember("Set", BindingFlags.CreateInstance, null, val, new object[] { val.Length }); MethodInfo method = errType.GetMethod("GetValue", new Type[] { typeof(int) }); for (int i = 0; i < val.Length; i++) { ErrorMessage.ErrorData err = new ErrorMessage.ErrorData(); object val2 = method.Invoke(val, new object[] { 0 }); Type errWS = val2.GetType(); foreach (FieldInfo field in errWS.GetFields()) { switch (field.Name) { case "ID": err.ID = field.GetValue(val2).ToString(); break; case "Message": err.Message = field.GetValue(val2).ToString(); break; } } errdata.Add(err); } } else { object val = item.GetValue(obj); switch (item.Name) { case "ErrorCode": errMsg.ErrorCode = Convert.ToInt32(val); break; case "ErrorMsg": errMsg.ErrorMsg = val.ToString(); break; } } } errMsg.ErrorList = errdata.ToArray(); return errMsg; } /// <summary> /// SOAP头 /// </summary> public class SoapHeader { /// <summary> /// 构造一个SOAP头 /// </summary> public SoapHeader() { this.Properties = new Dictionary<string, object>(); } /// <summary> /// 构造一个SOAP头 /// </summary> /// <param name="className">SOAP头的类名</param> public SoapHeader(string className) { this.ClassName = className; this.Properties = new Dictionary<string, object>(); } /// <summary> /// 构造一个SOAP头 /// </summary> /// <param name="className">SOAP头的类名</param> /// <param name="properties">SOAP头的类属性名及属性值</param> public SoapHeader(string className, Dictionary<string, object> properties) { this.ClassName = className; this.Properties = properties; } /// <summary> /// SOAP头的类名 /// </summary> public string ClassName { get; set; } /// <summary> /// SOAP头的类属性名及属性值 /// </summary> public Dictionary<string, object> Properties { get; set; } /// <summary> /// 为SOAP头增加一个属性及值 /// </summary> /// <param name="name">SOAP头的类属性名</param> /// <param name="value">SOAP头的类属性值</param> public void AddProperty(string name, object value) { if (this.Properties == null) { this.Properties = new Dictionary<string, object>(); } Properties.Add(name, value); } } } }
-------------------------------------------------------------------
服务器端方法和对象
对象:
using System; using System.Web.Services.Protocols; using IDPSystem.BLL; using IDPSystem.BLL.DictionaryEnum.StaffRole; namespace IDPSystem.WebUI.WebService { /// <summary> /// 用户认证用的数据 /// </summary> public class Certificate : SoapHeader { public Certificate() { } /// <summary> /// 用户名 /// </summary> public string LoginUserName { get; set; } /// <summary> /// 密码 /// </summary> public string LoginPassword { get; set; } } /// <summary> /// WebService使用的数据 /// </summary> [Serializable] public class Staff { #region 属性 /// <summary> /// 员工ID /// </summary> public string Identity { get; set; } /// <summary> /// 员工编号 /// </summary> public string Number { get; set; } /// <summary> /// 员工姓名 /// </summary> public string Name { get; set; } /// <summary> /// 离职状态 /// </summary> public bool Dimission { get; set; } /// <summary> /// 数据最后一次更新用户 /// </summary> internal string LastUpdateUserInfoID { get; set; } /// <summary> /// 登陆用户信息 /// </summary> internal string UserInfoIdentity { get; set; } /// <summary> /// 公司ID /// </summary> internal string CorparionID { get; set; } #endregion #region 构造函数 public Staff() { this.UpdateTime = DateTime.Now.ToString(); this.InsertTime = DateTime.Now.ToString(); } /// <summary> /// WebService返回值 /// </summary> public class WS_ErrorMessage { public struct ErrorData { public string ID; public string Message; public ErrorData(string id, string msg) { this.ID = id; this.Message = msg; } } /// <summary> /// 返回错误信息结果集 /// </summary> private ErrorData[] errorList; public ErrorData[] ErrorList { get { return errorList; } set { errorList = value; } } /// <summary> /// 错误码 0成功 1失败 2部分成功 /// </summary> private int errorCode; public int ErrorCode { get { return errorCode; } set { errorCode = value; } } /// <summary> /// 错误信息 /// </summary> private string errorMsg; public string ErrorMsg { get { return errorMsg; } set { errorMsg = value; } } } }
方法:
[XmlInclude(typeof(Staff[])), XmlInclude(typeof(ErrorMessage)), XmlInclude(typeof(IDPSystem.WebUI.WebService.WS_ErrorMessage.ErrorData))] public class WS_StaffOperate : System.Web.Services.WebService { /// <summary> /// 验证权限 /// </summary> public Certificate certificate = new Certificate(); [SoapHeader("certificate")] [WebMethod] public WS_ErrorMessage HelloWorld(Staff staff) { } }
--------------------------------------
客户端对象:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace WebServiceTest { public class ErrorMessage { public class ErrorData { public string ID; public string Message; public ErrorData(string id, string msg) { this.ID = id; this.Message = msg; } public ErrorData() { } } /// <summary> /// 返回错误信息结果集 /// </summary> private ErrorData[] errorList; public ErrorData[] ErrorList { get { return errorList; } set { errorList = value; } } /// <summary> /// 错误码 0成功 1失败 2部分成功 /// </summary> private int errorCode; public int ErrorCode { get { return errorCode; } set { errorCode = value; } } /// <summary> /// 错误信息 /// </summary> private string errorMsg; public string ErrorMsg { get { return errorMsg; } set { errorMsg = value; } } } }