C动态调用WebService
一、前言
在工作中要切换多个环境的WebService地址,如果使用静态引用会导致无法切换环境地址,从而通过动态调用的方式解决该问题。,如果涉及到与第三方进行接口对接,有的会使用WebService的方式,这篇文章主要讲解在.NET Framework中如何调用WebService。首先我们创建一个WebService,里面有两个方法:一个无参的方法,一个有参的方法:
创建好了WebService以后,把WebService部署到IIS上,并确保可以访问
二、静态引用
这种方式是通过添加静态引用的方式调用WebService。首先创建一个Winform程序,界面上有一个按钮,点击按钮调用WebService:
然后添加静态引用。在要调用WebService的项目上选择引用,然后右键选择"添加服务引用",如下图所示:
然后输入IIS上部署的WebService地址:
最后点击"确定"按钮即可完成静态引用WebService,添加完成以后的项目结构如下图所示:
添加完引用以后,就可以编写代码了:
///
/// 静态调用WebService
///
///
///
private void btn_Static_Click(object sender, EventArgs e)
{
// 实例化类
CallWebService.TestWebSoapClient client = new CallWebService.TestWebSoapClient();
// 调用无参的HelloWorld方法
string value1= client.HelloWorld();
// 调用有参的方法
string value2 = client.Test("有参方法");
// 输出
MessageBox.Show(#34;无参方法返回值:{value1},有参方法返回值:{value2}");
}
运行程序测试:
这样就可以实现调用WebService了。
三、动态调用
上面我们说了如何使用静态引用的方式调用WebService,但是这种方式有一个缺点:如果发布的WebService地址改变,那么就要重新添加WebService的引用。如果是现有的WebService发生了改变,也要更新现有的服务引用,这需要把代码放到现场才可以。那么有没有什么方式可以解决这种问题呢?那就是使用动态调用WebService的方法。
我们在配置文件里面添加配置,把WebService的地址、WebService提供的类名、要调用的方法名称,都写在配置文件里面:
在界面上添加一个按钮,点击按钮可以动态调用WebService,新建一个帮助类:
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.Web.Services.Description;
using System.Xml.Serialization;
namespace WebServiceDemo
{
public class WebServiceHelper
{
///
/// 生成dll文件保存到本地
///
/// WebService地址
/// 类名
/// 方法名
/// 保存dll文件的路径
public static void CreateWebServiceDLL(string url,string className, string methodName,string filePath )
{
// 1. 使用 WebClient 下载 WSDL 信息。
WebClient web = new WebClient();
Stream stream = web.OpenRead(url + "?WSDL");
// 2. 创建和格式化 WSDL 文档。
ServiceDescription description = ServiceDescription.Read(stream);
//如果不存在就创建file文件夹
if (Directory.Exists(filePath) == false)
{
Directory.CreateDirectory(filePath);
}
if (File.Exists(filePath + className + "_" + methodName + ".dll"))
{
//判断缓存是否过期
var cachevalue = HttpRuntime.Cache.Get(className + "_" + methodName);
if (cachevalue == null)
{
//缓存过期删除dll
File.Delete(filePath + className + "_" + methodName + ".dll");
}
else
{
// 如果缓存没有过期就直接返回
return;
}
}
// 3. 创建客户端代理代理类。
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
// 指定访问协议。
importer.ProtocolName = "Soap";
// 生成客户端代理。
importer.Style = ServiceDescriptionImportStyle.Client;
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;
// 添加 WSDL 文档。
importer.AddServiceDescription(description, null, null);
// 4. 使用 CodeDom 编译客户端代理类。
// 为代理类添加命名空间,缺省为全局空间。
CodeNamespace nmspace = new CodeNamespace();
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace);
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters parameter = new CompilerParameters();
parameter.GenerateExecutable = false;
// 可以指定你所需的任何文件名。
parameter.OutputAssembly = filePath + className + "_" + methodName + ".dll";
parameter.ReferencedAssemblies.Add("System.dll");
parameter.ReferencedAssemblies.Add("System.XML.dll");
parameter.ReferencedAssemblies.Add("System.Web.Services.dll");
parameter.ReferencedAssemblies.Add("System.Data.dll");
// 生成dll文件,并会把WebService信息写入到dll里面
CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit);
if (result.Errors.HasErrors)
{
// 显示编译错误信息
System.Text.StringBuilder sb = new StringBuilder();
foreach (CompilerError ce in result.Errors)
{
sb.Append(ce.ToString());
sb.Append(System.Environment.NewLine);
}
throw new Exception(sb.ToString());
}
//记录缓存
var objCache = HttpRuntime.Cache;
// 缓存信息写入dll文件
objCache.Insert(className + "_" + methodName, "1", null, DateTime.Now.AddMinutes(5), TimeSpan.Zero, CacheItemPriority.High, null);
}
}
}
动态调用WebService代码:
///
/// 动态调用WebService
///
///
///
private void btn_Dynamic_Click(object sender, EventArgs e)
{
// 读取配置文件,获取配置信息
string url = ConfigurationManager.AppSettings["WebServiceAddress"];
string className = ConfigurationManager.AppSettings["ClassName"];
string methodName = ConfigurationManager.AppSettings["MethodName"];
string filePath = ConfigurationManager.AppSettings["FilePath"];
// 调用WebServiceHelper
WebServiceHelper.CreateWebServiceDLL(url, className, methodName, filePath);
// 读取dll内容
byte[] filedata = File.ReadAllBytes(filePath + className + "_" + methodName + ".dll");
// 加载程序信息
Assembly asm = Assembly.Load(filedata);
Type t = asm.GetType(className);
// 创建实例
object o = Activator.CreateInstance(t);
MethodInfo method = t.GetMethod(methodName);
// 参数
object[] args = {"动态调用WebService" };
// 调用访问,获取方法返回值
string value = method.Invoke(o, args).ToString();
//输出返回值
MessageBox.Show(#34;返回值:{value}");
}
程序运行结果:
如果说类名没有提供,可以根据url来自动获取类名:
///
/// 根据WebService的url地址获取className
///
/// WebService的url地址
///
private string GetWsClassName(string wsUrl)
{
string[] parts = wsUrl.Split("/");
string[] pps = parts[parts.Length - 1].Split(".");
return pps[0];
}
顶配千元机和低配旗舰机怎么选?区别有3处,不花冤枉钱手机分为百元机千元机旗舰机以及高端机皇,每一类机型都有自己的特点,而且价格也不同,不过在选择手机的时候,大家都会陷入一个误区,是买顶配千元机还是低配旗舰机?顶配千元机的价格都在20
盘点市面上几大热门折叠方案,三星华为OPPO你更青睐哪款?不知道大家发现了没有,现在折叠屏市场可谓是达到了异常火爆的程度,各大手机厂商都纷纷推出了全新的折叠屏产品,并且各家都挖掘出不同的折叠屏形式,一种是上下折叠屏的翻盖模式,目前华为P5
手机不要装这样的软件,只会越来越卡大家好,我们用的智能手机新买的时候运行很快,但是在用了一段时间后,会出现卡顿,广告越来越多甚至无法使用的情况,那么看看手机里是否安装了这些软件1,杀毒软件。在我们平时玩儿手机时会弹
严重怀疑APP故意与系统对立,从而造成手机卡顿问题问过很多用苹果手机的人,都说系统不更新,APP不更新,除非APP用不了,才更新。安卓手机,大家都说卡顿,很多人找原因说是系统问题,是系统碎片无法化解问题,我要说的是,不是系统,是A
最新电脑配置推荐与方向本文以帮助小白找到更好更合适的电脑硬件为目标而不断的改进,本文纯用爱发电,主观上没有任何暗箱操作,可放心阅读。如果可以的话,大家可以给这篇文章点一个赞吗?也可以关注我们微信公众(装
元宇宙脑机接口之黑客帝国4这世界上只存在着一种永恒?世间真的存在唯一的真理?何为真?往往只不过是从一个牢笼到另外一牢笼,不同的群体有不同价值倾向不同的范畴,有些人喜欢追逐自由,也有些人喜欢安定,人们总是在所
华为mate50系列年底发布搭载麒麟9000处理器今日微博博主曝光了华为Mate50系列的相关消息,新机将于今年年底发布,搭载麒麟9000处理器,并且还将有新一代骁龙8处理器版本发布,新机后置摄像头模组采用大圆环设计,内置五颗摄像
ZTELiveBudsPro六麦硬核降噪安静聆听在蓝牙耳机领域,无论是老牌音响厂家还是新生代终端公司都加入了这个领域的厮杀,一些手机厂家也开始推出了自己的TWS耳机,如小米华为魅族中兴等,2021年7月27日晚7点,在Axon3
台式电脑的显示器怎么选作为一个相当于科普类的文章,我不太想将文章写成品牌带货,所以我更偏向于对各类参数进行解说,让大家能更了解怎么选,哪些参数是购买前需要重点关注,而哪些参数不用太注意。对于显示器有以下
咪鼠智能语音鼠标M5,这一次咪鼠重新定义鼠标,是否值得期待呢鼠标作为电脑外接输入的设备,使电脑的操作变得更加简便快捷。但随着鼠标功能的多元化,也使得电脑的操作变得更加丰富多彩了,满足了多场景的使用需求。在多场景的使用中,使用较多的场景来自于
救命文档刷屏朋友圈背后数字共建可在灾害黄金救援时间发挥巨大能量2021年,河南省遭遇罕见特大暴雨时,一份名为待救援人员信息的文档曾被广泛转发,刷屏朋友圈,被称为救命文档。这份文档背后,是一层层由求助者救援者志愿者组成的民间互助网络,也是地方政