当前位置:首页 > Web开发 > 正文

动态调用WebService接口的几种方式

2024-03-31 Web开发

标签:

一、什么是WebService?

这里就不再赘述了,想要了解的====》传送门

二、为什么要动态调用WebService接口?

一般在C#开发中调用webService服务中的接口都是通过引用过来就行调用的,步骤如下:

1.找到引用,右击添加服务引用,找到高级,添加web引用,添加之后就可以直接调用里面的方法。

技术图片

 

技术图片

技术图片

以上这种方法是最简单粗暴的一种方式。当然在开发中总是不那么如意,以上方式是在本机直接可以访问服务的地址,假如在本机不能直接访问WebService,那么就会有些蛋疼。

这种方式就不可取了,那么有什么方式可以不直接访问就可以开发呢?这就要使用动态调用的方式进行调用了。接下来就是如何动态调用WebService了。

三、动态调用WebService的几种方式

 方式一:

随便百度一下就可以找到的一种,接下了的代码来源于百度找到的并性能进行优化升级过。

public static class CommonServiceHelper { /// <summary> /// 静态缓存字典,速度提升至8倍 /// </summary> private static Dictionary<string, object> _webServiceConfig = new Dictionary<string, object>(); //获取WSDL private static readonly WebClient wc = new WebClient(); /// < summary> /// 动态调用web服务 /// </summary> /// < param>WSDL服务地址</param> /// < param>类名</param> /// < param>方法名</param> /// < param>参数</param> /// < returns></returns> public static object InvokeWebService(this string url, string methodname, object[] args, string classname = "") { string key = $"{url}_{methodname}";//缓存Key唯一标识 Type webService; if (!_webServiceConfig.ContainsKey(key)) { string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling"; //classname 一般自己指定 如果有些地址是http://?wsdl 就会调用失败 if ((classname == null) || (classname == "")) { classname = GetWsClassName(url); } try { Stream stream = wc.OpenRead(url); ServiceDescription sd = ServiceDescription.Read(stream); ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); sdi.AddServiceDescription(sd, "", ""); CodeNamespace cn = new CodeNamespace(@namespace); CodeCompileUnit ccu = new CodeCompileUnit(); ccu.Namespaces.Add(cn); sdi.Import(cn, ccu); CSharpCodeProvider icc = new CSharpCodeProvider(); CompilerParameters cplist = new CompilerParameters { GenerateExecutable = false, 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 compiler = icc.CompileAssemblyFromDom(cplist, ccu); icc.Dispose(); if (compiler.Errors.HasErrors) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (CompilerError ce in compiler.Errors) { sb.Append(ce.ToString()); sb.Append(Environment.NewLine); } throw new Exception(sb.ToString()); } System.Reflection.Assembly assembly = compiler.CompiledAssembly; Type t = assembly.GetType(@namespace + "." + classname, true, true); webService = t; _webServiceConfig.Add(key, webService);//加入缓存 } catch (Exception ex) { throw new Exception(ex.Message); } } else { webService = _webServiceConfig[key] as Type;//获取缓存的数据 } if (webService != null) { object obj = Activator.CreateInstance(webService); System.Reflection.MethodInfo mi = webService.GetMethod(methodname); if (mi != null) { return mi.Invoke(obj, args); } throw new Exception($"找不到{methodname}这个方法,调用失败"); } else { throw new Exception($"WebService 对象为空,调用失败"); } } /// <summary> /// 获取wsdl类名称 /// </summary> /// <param>wsdl地址</param> /// <returns></returns> private static string GetWsClassName(string wsUrl) { string[] parts = wsUrl.Split(/); string[] pps = parts[parts.Length - 1].Split(.);//classname 一般自己指定 原因是因为在这里 return pps[0]; } /// <summary> /// 清空缓存 /// </summary> public static void ClearCache() { _webServiceConfig.Clear(); } }

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/41114.html