前言:访问webservice,大多数人都是用服务引用的方式,但是这种方式比较麻烦,例如遇到服务更新了,你还需要手动更新你的服务引用,再重新发布,很麻烦。或者已有的一些例子,至少我看到的很多案例,动态访问也只能止步于使用.net framework环境,没看到有啥.net core上面动态访问的案例。于是我就来抛砖引玉一下,自己写一个支持.net framework也可以支持.netcore或以上环境使用的动态访问webservice服务接口的方法,供大家使用或参考。
 
先创建一个webservice服务,用来测试使用。提供三个服务接口,一个无参数、一个字符串参数、一个含有多个实体类参数(实体类参数也含有嵌套和集合)以及返回带有嵌套和集合的返回数据,用来做测试使用,基本上可以涵盖几乎所有的webservice服务的情况了。
有关测试实体类
启动webservice服务备用
 
请求端程序,支持.netframework 4.6.1+、.net core+和.net 5+所有版本,都可以通过nuget来引用 Wesky.Net.OpenTools 包。需要引用最新的版本,以保证功能完善。我此处使用.net 8的控制台来引用,大佬们可以根据自己程序情况进行引用,framework4.6以下版本不适用。
为了方便使用,我本地也直接编写几个实体类,用来传参和做返回值接收使用:
先实例化一个WebserviceHelper对象,如果有用IOC容器的大佬,比如说使用asp.net core程序等,可以对该接口和类进行依赖注入的注册。如果没用IOC容器的大佬,可以直接这样new一个使用。此处我用new一个对象的使用方式来使用。并且获取到asmx的url地址,地址此处需要添加?wsdl后缀。
申明要访问的服务的名称,例如HelloWorld,然后直接调用。由于没有参数,所以参数直接设为null
运行程序进行调用,可以看到获取到了返回值的xml文档。
直接调用的时候,返回值是一个 OpenToolResult类型,类型定义如下:
由于咱们的返回值就一个基础类型string,所以需要调用解析基础类型值的方法,得到最终的返回消息为 Hello World。
基础类型值解析方法定义如下:
传入参数为:获取到的返回值、节点名称(一般是方法名称+“Result”)、命名空间,命名空间在调用的时候,会被存储到类型OpenWebserviceInfo的属性OpenWebservice集合(是一个OpenWebserviceDocCache类型的集合)里面去,通过url地址和接口方法名字可以匹配到对应的命名空间。
OpenWebserviceDocCache类型定义如下:
 
接着试一下传入一个基础类型参数的情况。访问Hola方法,传入Wesky字符串,成功获取到返回值 Wesky World。
 
接下来试一下传入多个实体类参数,并且按照上面webservice的内容,会返回一个其他一个实体类消息。
回看一下TestService服务接口的实现,说明动态访问是成功的。
访问webservice方法定义说明。参数可以传0个或多个参数,会用来和解析度wsdl地址的同名方法服务参数个数做匹配,如果不匹配,则会提示错误信息。返回值Result.IsSuccess如果是true,代表发送请求成功;如果解析错误或者发送请求失败等,则提示false,并且Message属性会有具体错误信息描述。
返回值为实体类的解析方法定义说明。以上请求TestSevice服务接口时候,返回值是实体类,如果需要匹配本地的实体类,需要访问 ExtractCustomerValueFromXml方法进行解析处理。例如上面传入的是ResultInfo类型作为返回值接收类。
一些核心代码:
  /// <summary>
/// 调用Web服务
/// Calls a web service.
/// </summary>
/// <param name="url">服务URL / Service URL</param>
/// <param name="apiName">API名称 / API name</param>
/// <param name="expireSecond">过期时间(秒)/ Expiration time in seconds</param>
/// <param name="parameters">调用参数 / Invocation parameters</param>
/// <returns>调用结果 / Invocation result</returns>
public OpenToolResult<string> CallWebservice(string url, string apiName,long expireSecond = 86400,params object[] parameters)
{
OpenToolResult<string> result = new HttpExtensions.OpenToolResult<string>(); CheckExpireTime(url, apiName, expireSecond); var wsInfo = OpenWebserviceInfo.OpenWebservice.FirstOrDefault(x => x.WebserviceUrl == url && x.OperationName == apiName); if (wsInfo == null)
{
result.IsSuccess = false;
result.Message = "本地无法加载远程webservice服务。Cannot load the remote webservice locally.";
return result;
} if ((parameters == null && wsInfo.ParameterNames.Count > 0) || (parameters!=null && parameters.Length != wsInfo.ParameterNames.Count))
{
result.IsSuccess = false;
result.Message = $"远程服务接口参数个数和你传入的参数个数不匹配。远程服务参数个数:{wsInfo.ParameterNames.Count}, 本地传入参数个数: {parameters?.Length ?? 0}。Parameter count mismatch: remote service has {wsInfo.ParameterNames.Count}, provided {parameters?.Length ?? 0}.";
return result;
} Dictionary<string, string> dicParams = new Dictionary<string, string>();
if (parameters != null)
{
for (int i = 0; i < wsInfo.ParameterNames.Count; i++)
{
dicParams.Add(wsInfo.ParameterNames[i], XmlConvertor.SerializeObjectToXml(parameters[i]));
}
}
var response = InvokeService(url, apiName, dicParams,wsInfo.Namespace); result.Result = response;
result.IsSuccess = true;
result.Message = "success"; return result;
}
如果以上内容对你有帮助,欢迎点赞、转发、在看和关注我的个人公众号:【Dotnet Dancer】
 
如果需要以上演示代码和webservice测试源码,可以在公众号【Dotnet Dancer】后台回复“动态接口”进行下载。
 
OpenTools系列文章快捷链接【新版本完全兼容旧版本,不需要更新任何代码均可使用】:
1.0.11版本
如何一行C#代码实现解析类型的Summary注释(可用于数据字典快速生成)
1.0.10版本:
C#/.NET一行代码把实体类类型转换为Json数据字符串
1.0.8版本:
上位机和工控必备!用.NET快速搞定Modbus通信的方法
1.0.7版本:
大揭秘!.Net如何在5分钟内快速实现物联网扫码器通用扫码功能?
1.0.6版本:
.NET实现获取NTP服务器时间并同步(附带Windows系统启用NTP服务功能)
1.0.5版本:
C#使用P/Invoke来实现注册表的增删改查功能
1.0.3版本:
C#实现图片转Base64字符串,以及base64字符串在Markdown文件内复原的演示
1.0.2版本:
​C#实现Ping远程主机功能(支持IP和域名)
1.0.1版本:
开始开源项目OpenTools的创作(第一个功能:AES加密解密)
 
【备注】包版本完全开源,并且没有任何第三方依赖。使用.net framework 4.6+、任意其他跨平台.net版本环境,均可直接引用。

谁说.net core不好动态访问webservice?看这篇文章,C#快速实现动态访问webservice,兼容.net framework和.net core+的更多相关文章

  1. Android动态方式破解apk前奏篇(Eclipse动态调试smail源码)

    一.前言 今天我们开始apk破解的另外一种方式:动态代码调试破解,之前其实已经在一篇文章中说到如何破解apk了: Android中使用静态方式破解Apk  主要采用的是静态方式,步骤也很简单,首先使用 ...

  2. .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

    最近有个需求就是一个抽象仓储层接口方法需要SqlServer以及Oracle两种实现方式,为了灵活我在依赖注入的时候把这两种实现都给注入进了依赖注入容器中,但是在服务调用的时候总是获取到最后注入的那个 ...

  3. 【NET CORE微服务一条龙应用】第三章 认证授权与动态权限配置

    介绍 系列目录:[NET CORE微服务一条龙应用]开始篇与目录 在微服务的应用中,统一的认证授权是必不可少的组件,本文将介绍微服务中网关和子服务如何使用统一的权限认证 主要介绍内容为: 1.子服务如 ...

  4. ExpandoObject与DynamicObject的使用 RabbitMQ与.net core(一)安装 RabbitMQ与.net core(二)Producer与Exchange ASP.NET Core 2.1 : 十五.图解路由(2.1 or earler) .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

    ExpandoObject与DynamicObject的使用   using ImpromptuInterface; using System; using System.Dynamic; names ...

  5. ASP.NET中WebService的创建和部署以及通过反射动态调用WebService

    一.在ASP.NET中创建WebService 首先我们先创建一个ASP.NET Web 应用程序,此处我们以VS2017为例 点击新创建的项目,右键添加新建项,选择Web服务,输入名称后点击添加 这 ...

  6. WebService只能在本地使用,无法通过网络访问的解决办法

    问题描述:WebService只能在本地使用,无法通过网络访问. 解决方案:在web.config的<system.web></system.web>中间加入如下配置节内容: ...

  7. 使用Entity Framework Core访问数据库(Oracle篇)

    前言 哇..看看时间 真的很久很久没写博客了 将近一年了. 最近一直在忙各种家中事务和公司的新框架  终于抽出时间来更新一波了. 本篇主要讲一下关于Entity Framework Core访问ora ...

  8. 基于SqlSugar的数据库访问处理的封装,支持.net FrameWork和.net core的项目调用

    由于我们有时候需要在基于.net framework的项目上使用(如Winform端应用),有时候有需要在.net core的项目上使用(如.net core的WebAPI),那么我们把基于SQLSu ...

  9. NET?.NET Framework?.NET Core?

    什么是.NET?什么是.NET Framework?什么是.NET Core? https://www.cnblogs.com/1996V/p/9037603.html 什么是.NET?什么是.NET ...

  10. Vue + Element UI 实现权限管理系统 前端篇(十):动态加载菜单

    动态加载菜单 之前我们的导航树都是写死在页面里的,而实际应用中是需要从后台服务器获取菜单数据之后动态生成的. 我们在这里就用上一篇准备好的数据格式Mock出模拟数据,然后动态生成我们的导航菜单. 接口 ...

随机推荐

  1. 为了让你在“口袋奇兵”聊遍全球,Serverless 做了什么?

    简介: 江娱互动是一家新兴的游戏企业,自 2018 年成立伊始,江娱互动就面向广阔的全球游戏市场,通过创造有趣的游戏体验,在竞争激烈的游戏市场占得一席之地.仅仅 2 年的时间,江娱互动就凭借 Topw ...

  2. 基于链路思想的SpringBoot单元测试快速写法

    ​简介:本文更偏向实践而非方法论,所提及的SpringBoot单元测试写法亦并非官方解,仅仅是笔者自身觉得比较方便.效率较高的一种写法.每个团队甚至团队内的每位开发可能都有自己的写法习惯和风格,只要能 ...

  3. 解密万亿参数M6模型预训练背后的分布式框架Whale

    ​简介: 最近,阿里云PAI团队和达摩院智能计算实验室一起发布"低碳版"巨模型M6,大幅降低万亿参数超大模型训练能耗.借助我们自研的Whale框架仅使用480卡GPU,即训练出了规 ...

  4. [Go] 让 go build 生成的可执行文件对 Mac、linux、Windows 平台一致

    要做到这一点,使用的是交叉编译选项. CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go CGO_ENABLED=0 GOOS=windows ...

  5. dotnet 修复在 Linux 上使用 SkiaSharp 提示找不到 libSkiaSharp 库

    本文告诉大家如何简单修复在 Linux 上使用 SkiaSharp 提示找不到 libSkiaSharp 库 我的应用在 Windows 上跑的好好的,放在 Linux 上一运行就炸掉了,异常内容如下 ...

  6. localstory,sessionstory,vuex,cook

    函数式组件 1.特点 没有this(没有实例) 没有响应式数据 它只是一个接受一些 prop 的函数. render MVVM分为Model.View.ViewModel三者. Model:代表数据模 ...

  7. html+jq实现全国省的单选,弹框输入input

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...

  8. hbuilder打包报错:java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 7 column 15 path $.icons

    一个棘手的问题,在网上找几乎没有出现这样的案例,个别也只有翻译没有解决方式,,,,,自己研究一番发现这实际上都不算是个问题 这句话翻译:这个位置应该是个对象而不是数组,解决方法: 在manifest. ...

  9. CF1097C Yuhao and a Parenthesis

    CF1097C Yuhao and a Parenthesis stl 乱搞做法,感觉比正解更直接. 每个字符串内部能匹配的尽可能匹配. 匹配完成后,检验剩余序列是否只含有 ( 或只含有 ) 或为空, ...

  10. 老外为了在MacBook上玩原神,让M1支持了所有iOS应用 | Github每周精彩分享第一期

    大家好,这里是每周更新的Github有趣项目分享,我是每周都在吃瓜的蛮三刀酱. 我会从Github热门榜里选出 高质量.有趣,牛B 的开源项目进行分享. 废话不多说,看看最近有什么有意思的Github ...