动态调用WebService接口的几种方式
一、什么是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 name="url">WSDL服务地址</param>
/// < param name="classname">类名</param>
/// < param name="methodname">方法名</param>
/// < param name="args">参数</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://www.webxml.com.cn/WebServices/WeatherWS?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 name="wsUrl">wsdl地址</param>
/// <returns></returns>
private static string GetWsClassName(string wsUrl)
{
string[] parts = wsUrl.Split('/');
string[] pps = parts[parts.Length - ].Split('.');//classname 一般自己指定 原因是因为在这里
return pps[];
}
/// <summary>
/// 清空缓存
/// </summary>
public static void ClearCache()
{
_webServiceConfig.Clear();
}
}
以上方法是第一种,这种方法不是万能的,因为方法是通过反射调用的,多个参数的时候顺序不能乱,方法名称不能写错,对于有些WebService是无法调用的。
方式二:
这种方式针对本机不能访问的WebService非常有效,参数啥的不容易搞混,跟C#直接添加引用之后调用方式一样。
C#添加引用的方式是通过对于WebService的xml进行解析并生成相关代码,根据原理可知,只要有WebService的xml就好办了。
对于本机不能访问的WebService,找个可以访问的环境,用浏览器进行访问,后面加上wsdl,例如:http://www.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl
然后进行访问,把页面另存为你可以找得到的地方。我这里直接存储到D盘

把这个xml文件丢到你本地随便一个可以访问的的站点下,这个xml文件要可以正常访问。(这个很重要)
接下来就要使用visual studio 开发人员命令工具,我这里是使用vs2019 ,前面几个版本的vs都可以
在开始菜单里面找到并打开

接下来使用命令生成代码。
命令如下:wsdl 你本地访问的那个xml地址全路径
我这里是放在端口81的站点下

生成的cs类文件跟通过web引用生成的cs文件是一样,这样就可以解决本机不能直接访问WebService不能调用方法的问题。
当然,想要可以执行其中的方法还需要把代码放到对应环境上才能执行。
四、总结
以上是使用两种方式动态调用WebService接口的方式,在实际开发中,遇到不能访问的,一般用第二种比较保险。
动态调用WebService接口的几种方式的更多相关文章
- C#动态调用WCF接口,两种方式任你选。
写在前面 接触WCF还是它在最初诞生之处,一个分布式应用的巨作. 从开始接触到现在断断续续,真正使用的项目少之又少,更谈不上深入WCF内部实现机制和原理去研究,最近自己做一个项目时用到了WCF. 从这 ...
- Python调用API接口的几种方式 数据库 脚本
Python调用API接口的几种方式 2018-01-08 gaoeb97nd... 转自 one_day_day... 修改 微信分享: 相信做过自动化运维的同学都用过API接口来完成某些动作.AP ...
- Python调用API接口的几种方式
Python调用API接口的几种方式 相信做过自动化运维的同学都用过API接口来完成某些动作.API是一套成熟系统所必需的接口,可以被其他系统或脚本来调用,这也是自动化运维的必修课. 本文主要介绍py ...
- 动态调用webservice 接口
1.url:http://localhost:8002/名称.asmx(asmx结尾) 2.需要引用的命名空间:System.Web.Services 3.调用代码: public class Dyn ...
- java调用CXF WebService接口的两种方式
通过http://localhost:7002/card/services/HelloWorld?wsdl访问到xml如下,说明接口写对了. 2.静态调用 // 创建WebService客户端代理工厂 ...
- 【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】
不考虑第三方框架,如果只使用JDK提供的API,那么可以使用三种方式调用WebService服务:另外还可以使用Ajax调用WebService服务. 预备工作:开启WebService服务,使用jd ...
- c#动态调用WEBSERVICE接口
C#动态webservice调用接口 1 using System; 2 using System.Collections; 3 using System.IO; 4 using System.Net ...
- java调用http接口的几种方式总结
本文参考: https://blog.csdn.net/fightingXia/article/details/71775516 https://www.cnblogs.com/jeffen/p/69 ...
- SoapUI调用webservice实现的两种方式
SoapUI用来做测试,已经是很多人做过的事情了,而且网上教程也很多.不过还是写下来,对比webservice协议与http协议脚本编写的不同. 首先测接口得有一个服务,刚好笔者所在项目做ESB集成. ...
随机推荐
- Python3学习笔记-更新中
1.Python概况 2.Anaconda安装及使用 3.Pycharm安装及使用 4.Hello World!!! 5.数据类型及类型转换 6.分支结构 7.循环语句 8.异常
- python并发编程-进程池线程池-协程-I/O模型-04
目录 进程池线程池的使用***** 进程池/线程池的创建和提交回调 验证复用池子里的线程或进程 异步回调机制 通过闭包给回调函数添加额外参数(扩展) 协程*** 概念回顾(协程这里再理一下) 如何实现 ...
- Hive 教程(一)-安装与配置解析
安装就安装 ,不扯其他的 hive 依赖 在 hive 安装前必须具备如下条件 1. 一个可连接的关系型数据库,如 Mysql,postgresql 等,用于存储元数据 2. hadoop,并启动 h ...
- 基于MatConvNet的CNN图像搜索引擎PicSearch
简介 Picsearch是一种基于卷积神经网络特征的图像搜索引擎. Github:https://github.com/willard-yuan/CNN-for-Image-Retrieval Web ...
- 记一次完整的java项目压力测试
总结:通过这次压力测试,增加了对程序的理解:假定正常情况下方法执行时间为2秒,吞吐量为100/s,则并发为200/s:假设用户可接受范围为10s,那么并发量可以继续增加到1000/s,到这个时候一切还 ...
- awk--基本操作
二:awk--将一行分为数个字段处理 PS:awk [option] '条件类型 {动作1} 条件类型{动作2} ...' filename PS: awk 'Pattern {action}' fi ...
- 给网页中的button加动画效果
网页中的很多事件交互都是通过点击页面中的按钮来实现的,给按钮加一点动画效果也会让网页看起来生动一些,以下就是一个简单的例子: 此按钮的动画主要是通过css的transform动画,伪元素,伪类来实现: ...
- springboot mongodb jpa常用方法整理
官方文档https://docs.spring.io/spring-data/data-mongodb/docs/current/reference/html/index.html 查询: ***** ...
- Http option 请求是怎么回事
在前后台分离的项目中,经常会遇到浏览器想服务端发送一个post/patch请求,实际上产生了两个请求,一个是Option,另一个才是真实的Post/Patch请求, 而get请求则不会产生Option ...
- Scala新版本学习(1):
1.进官网:https://www.scala-lang.org/ 上面就是进入Scala社区后的一个画面,官方对Scala的简单介绍是:Scala将面向对象和函数式编程集合在一个简洁的高级语言中,S ...