WebService【WSDL】调用封装【已测试通过】
1.封装方法
/// <summary> /// 动态调用WebServers /// </summary> public static class WebServiceHelper { /// <summary> /// 存放程序集 /// </summary> private static Dictionary<string, MethodInfo> methodInfoDictionary = new Dictionary<string, MethodInfo>(); private static Dictionary<string, object> objectDictionary = new Dictionary<string, object>(); #region 对外调用 /// <summary> /// XML参数调用 /// </summary> /// <param name="url">服务地址</param> /// <param name="methodName">服务方法名</param> /// <param name="XmlParams">参数</param> /// <returns></returns> public static string GetInvokeWebServiceByJsonXml(string url, string methodName, object[] XmlParams) { try { string logMsg = string.Format("Invoke Method:url={0},methodName={1}", url, methodName); if (XmlParams != null && XmlParams.Length >= 2) { logMsg = string.Format(",XmlParams={0}", XmlParams[0] + Environment.NewLine + XmlParams[1]); } LogsHelper.LogsWriteTxt(logMsg); object obj = null; MethodInfo GetDatall = null; var result = GetInvokeWebServiceByObject(url, methodName, out obj, out GetDatall); LogsHelper.LogsWriteTxt($"服务是否调通:{result.ToString()}"); LogsHelper.LogsWriteTxt($"调用服务返回obj:{obj.ToString()}"); object ResObj = GetDatall.Invoke(obj, XmlParams); LogsHelper.LogsWriteTxt($"调用服务返回结果:{ResObj.ToString()}"); string xml = ResObj.ToString(); LogsHelper.LogsWriteTxt(string.Format("Invoke Method:Result={0}{1}", Environment.NewLine, xml)); return xml; } catch (Exception ex) { LogsHelper.LogsWriteTxt($"调用服务Error:{ex.ToString()}"); return ""; } } /// <summary> /// Json参数调用 /// </summary> /// <param name="url">服务地址</param> /// <param name="methodName">服务方法名</param> /// <param name="jsonParam">参数为Json</param> /// <returns></returns> public static string GetInvokeWebServiceByJson(string url, string methodName, string jsonParam) { try { string logMsg = string.Format("Invoke Method:url={0},methodName={1}", url, methodName); LogsHelper.LogsWriteTxt(logMsg); object obj = null; MethodInfo GetDatall = null; var result = GetInvokeWebServiceByObject(url, methodName, out obj, out GetDatall); LogsHelper.LogsWriteTxt($"服务是否调通:{result.ToString()}"); LogsHelper.LogsWriteTxt($"调用服务返回obj:{obj.ToString()}"); object ResObj = GetDatall.Invoke(obj, new object[] { jsonParam }); LogsHelper.LogsWriteTxt($"调用服务返回结果:{ResObj.ToString()}"); string getResult = ResObj.ToString(); LogsHelper.LogsWriteTxt(string.Format("Invoke Method:Result={0}{1}", Environment.NewLine, getResult)); return getResult; } catch (Exception ex) { LogsHelper.LogsWriteTxt($"调用服务Error:{ex.ToString()}"); return ""; } } /// <summary> /// 多参数调用 /// </summary> /// <param name="url">WebServices地址</param> /// <param name="methodname">调用的方法</param> /// <param name="args">把webservices里需要的参数按顺序放到这个object[]里</param> public static object GetInvokeWebService(string url, string methodname, string nameSpace, object[] args) { //这里的namespace是需引用的webservices的命名空间,我没有改过,也可以使用。也可以加一个参数从外面传进来。 string @namespace = nameSpace; try { //获取WSDL WebClient wc = new WebClient(); if (!url.EndsWith("?WSDL") && !url.EndsWith("?wsdl")) url = string.Format("{0}?WSDL", url); Stream stream = wc.OpenRead(url); ServiceDescription sd = ServiceDescription.Read(stream); string classname = sd.Services[0].Name; ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); sdi.ProtocolName = "Soap"; // 指定访问协议。 sdi.Style = ServiceDescriptionImportStyle.Client; // 生成客户端代理。 sdi.AddServiceDescription(sd, null, null); 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(); //设定编译参数 CompilerParameters cplist = new CompilerParameters(); cplist.GenerateExecutable = false;//动态编译后的程序集不生成可执行文件 cplist.GenerateInMemory = true;//动态编译后的程序集只存在于内存中,不在硬盘的文件上 cplist.ReferencedAssemblies.Add("System.dll"); cplist.ReferencedAssemblies.Add("System.XML.dll"); cplist.ReferencedAssemblies.Add("System.Web.Services.dll"); cplist.ReferencedAssemblies.Add("System.Data.dll"); //编译代理类 CompilerResults cr = csc.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()); } //生成代理实例,并调用方法 System.Reflection.Assembly assembly = cr.CompiledAssembly; Type t = assembly.GetType(@namespace + "." + classname, true, true); object obj = Activator.CreateInstance(t); System.Reflection.MethodInfo mi = t.GetMethod(methodname); //注:method.Invoke(o, null)返回的是一个Object,如果你服务端返回的是DataSet,这里也是用(DataSet)method.Invoke(o, null)转一下就行了,method.Invoke(0,null)这里的null可以传调用方法需要的参数,string[]形式的 return mi.Invoke(obj, args); } catch (Exception ex) { // LogHelper.Error("WS_Helper出现错误", ex); return null; } } #endregion 对外调用 #region 私有方法 /// <summary> /// 动态调用Webservices /// </summary> /// <param name="methodName">要调用的方法名称</param> /// <param name="url">服务地址</param> /// <returns></returns> private static bool GetInvokeWebServiceByObject(string url, string methodName, out object obj, out MethodInfo GetDatall) { obj = null; GetDatall = null; try { if (!methodInfoDictionary.TryGetValue(methodName, out GetDatall) || !objectDictionary.TryGetValue(methodName, out obj)) { url = url + "?WSDL"; //客户端代理服务命名空间,可以设置成需要的值。 string ns = string.Format("ProxyServiceReference"); //获取WSDL WebClient wc = new WebClient(); LogsHelper.LogsWriteTxt($"服务地址:{url}"); Stream stream = wc.OpenRead(url); ServiceDescription sd = ServiceDescription.Read(stream);//服务的描述信息都可以通过ServiceDescription获取 string classname = sd.Services[0].Name; ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); sdi.AddServiceDescription(sd, "", ""); CodeNamespace cn = new CodeNamespace(ns); //生成客户端代理类代码 CodeCompileUnit ccu = new CodeCompileUnit(); ccu.Namespaces.Add(cn); sdi.Import(cn, ccu); CSharpCodeProvider csc = new CSharpCodeProvider(); //设定编译参数 CompilerParameters cplist = new CompilerParameters(); cplist.GenerateExecutable = false; cplist.GenerateInMemory = true; cplist.ReferencedAssemblies.Add("System.dll"); cplist.ReferencedAssemblies.Add("System.XML.dll"); cplist.ReferencedAssemblies.Add("System.Web.Services.dll"); cplist.ReferencedAssemblies.Add("System.Data.dll"); //编译代理类 CompilerResults cr = csc.CompileAssemblyFromDom(cplist, ccu); if (cr.Errors.HasErrors == true) { 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()); } //生成代理实例 Assembly assembly = cr.CompiledAssembly; Type t = assembly.GetType(ns + "." + classname, true, true); GetDatall = t.GetMethod(methodName); obj = Activator.CreateInstance(t); methodInfoDictionary.Add(methodName, GetDatall); objectDictionary.Add(methodName, obj); } } catch (Exception ex) { LogsHelper.LogsWriteTxt($"动态调用Webservices失败,原因:{ex.ToString()}"); return false; } return true; } #endregion 私有方法 }
2.简单记录日志
/// <summary> /// 简单写入本地日志 /// </summary> public static class LogsHelper { public static void LogsWriteTxt(string strText, string strFileName = null) { try { if (strFileName == null || strFileName.Trim() == string.Empty) { strFileName = "Log" + DateTime.Now.ToString("yyyyMMdd") + ".txt"; } string getpath = AppDomain.CurrentDomain.BaseDirectory; if (Directory.Exists(getpath + "/日志信息") == false) { Directory.CreateDirectory(getpath + "/日志信息"); } string strFilePath = AppDomain.CurrentDomain.BaseDirectory + "手术状态回传日志\\" + strFileName; System.IO.StreamWriter sw = new System.IO.StreamWriter(strFilePath, true, System.Text.Encoding.Default); sw.WriteLine(strText); sw.Close(); } catch (Exception ex) { MessageBox.Show($"写入日志异常: { ex.Message}"); } } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步