十二、.net core(.NET 6)添加通用的访问webapi的方法(包括HttpClient和HttpWebRequest)
开发通用的访问webapi方法。
在common工具文件夹下,新建一个类库项目:Wsk.Core.WebHelper,并引用Package包项目,然后新建一个类HttpClientHelper,用于使用HttpClient方法进行访问webapi:

新建一个接口IHttpClientHelper,用于HttpClientHelper继承该接口。然后接口内新增一个返回泛型类型的通用的POST访问webapi的方法:

接着,在HttpClientHelper类里面,进行对该方法的实现:

说明:虽然使用了using,可以自动释放资源;但是难免还是需要一点时间。在finally下面通过手动释放资源,比自动释放资源,资源释放率会更快,在并发场景下,性能会更好一点点。当然,此处可以不适用using,因为手动释放了,以上纯属个人喜好的风格写法。
再来一个使用Basic加密进行访问的通用方法,写法如上,具体请看代码示例。先新建带用户名和密码参数的接口:

然后,在HttpClientHelper里面进行对应的实现:

以上为使用POST的方式进行,如果需要使用例如GET、PUT等,可以自行尝试,写法类似。
接口代码:

 
public interface IHttpClientHelper
{
/// <summary>
/// 通用访问webapi方法
/// </summary>
/// <param name="url"></param>
/// <param name="data"></param>
/// <returns></returns>
T Post<T>(string url, string data); /// <summary>
/// 带用户名和密码的通用访问webapi方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="data"></param>
/// <param name="account">用户名</param>
/// <param name="pwd">密码</param>
/// <returns></returns>
T Post<T>(string url, string data, string account, string pwd); }
实现类代码:

 
public class HttpClientHelper:IHttpClientHelper
{ readonly ILogger<HttpClientHelper> _logger; public HttpClientHelper(ILogger<HttpClientHelper> logger)
{
_logger = logger;
} public T Post<T>(string url, string data)
{
var result = default(T);
using (HttpClient client = new HttpClient())
{
try
{
client.Timeout = new TimeSpan(0, 0, 10); // 10是秒数,用于设置超时时长
HttpContent content = new StringContent(data);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
client.DefaultRequestHeaders.Connection.Add("keep-alive");
Task<HttpResponseMessage> res = client.PostAsync(url, content);
if (res.Result.StatusCode == System.Net.HttpStatusCode.OK)
{
result = JsonConvert.DeserializeObject<T>(res.Result.Content.ReadAsStringAsync().Result);
}
else
{
_logger.LogError($"访问webapi方法状态码错误:\r url:{url} \r data:{data} \r 状态码:{res.Result.StatusCode}");
}
}
catch (Exception ex)
{
_logger.LogError($"访问webapi方法异常:\r url:{url} \r data:{data} \r 异常信息:{ex.Message}");
}
finally
{
client.Dispose();
}
}
return result;
} public T Post<T>(string url, string data, string account, string pwd)
{
var result = default(T);
using (HttpClient client = new HttpClient())
{
try
{
string authorization = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(account + ":" + pwd));
client.DefaultRequestHeaders.Add("authorization", authorization); client.Timeout = new TimeSpan(0, 0, 10);
HttpContent content = new StringContent(data);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
Task<HttpResponseMessage> res = client.PostAsync(url, content);
if (res.Result.StatusCode == System.Net.HttpStatusCode.OK)
{
result = JsonConvert.DeserializeObject<T>(res.Result.Content.ReadAsStringAsync().Result);
}
else
{
_logger.LogError($"访问带用户名参数的webapi方法状态码错误:\r url:{url} \r data:{data} \r 状态码:{res.Result.StatusCode}");
}
}
catch (Exception ex)
{
_logger.LogError($"访问带用户名参数的webapi方法异常:\r url:{url} \r data:{data} \r 异常信息:{ex.Message}");
}
finally
{
client.Dispose();
}
}
return result;
} }
现在再新建一个使用HttpWebRequest的通用访问webapi的方式。在WebHelper项目下面,新建 HttpWebRequestHelper类,以及IHttpWebRequestHelper接口:

在接口里面,新建一个通用的泛型类型的访问webapi的请求接口:

然后,在HttpWebRequestHelper类里面,进行有关的实现:

HttpWebRequest没有Dispose方法,所以此处没有使用using写法,最后需要手动使用Abort方法进行释放资源。
接口代码:

 
public interface IHttpWebRequestHelper
{
/// <summary>
/// 通用方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="data"></param>
/// <param name="method">默认POST</param>
/// <returns></returns>
T Request<T>(string url, string data, string method = "POST");
}
接口实现代码:

 
public class HttpWebRequestHelper:IHttpWebRequestHelper
{
readonly ILogger<HttpWebRequestHelper> _logger; public HttpWebRequestHelper(ILogger<HttpWebRequestHelper> logger)
{
_logger = logger;
}
public T Request<T>(string url, string data,string method="POST")
{
var result = default(T);
HttpWebRequest request = null;
try
{
request = (HttpWebRequest)WebRequest.Create(url);
var byteData = Encoding.UTF8.GetBytes(data);
request.Method = method;
request.ContentType = "application/json";
request.ContentLength = data.Length;
request.Timeout = 10000; // 超时时间,毫秒单位
using (var stream = request.GetRequestStream())
{
stream.Write(byteData, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse(); // 发送请求
using (var resStream = response.GetResponseStream()) // 读取数据
{
using (var reader = new StreamReader(resStream, Encoding.UTF8))
{
result = JsonConvert.DeserializeObject<T>(reader.ReadToEnd());
}
}
}
catch (Exception ex)
{
_logger.LogError($"使用HttpWebRequest访问webapi方法异常:\r url:{url} \r data:{data} \r 异常信息:{ex.Message}");
}
finally
{
if (request != null)
{
request.Abort(); // 释放资源
}
}
return result;
}
}
现在开发两个webapi进行测试。首先把该类库项目,添加到启动项目的项目引用里面。然后,在启动项目里面的AutofacRegister里面,添加对Wsk.Core.WebHelper类库项目的所有接口进行依赖注入注册:

注册部分代码:
var assemblysWebhelper = Assembly.Load("Wsk.Core.WebHelper"); //
            container.RegisterAssemblyTypes(assemblysWebhelper)
                .SingleInstance()
               .AsImplementedInterfaces()
               .EnableInterfaceInterceptors();
新建一个实体类,用来当作参数和返回值的测试:

接着,在控制器里面写几个测试方法进行测试,测试内容如下:

控制器部分代码:

 
 [Route("[controller]/[action]")]
    [ApiController]
    public class WSKController : ControllerBase
    {
        private readonly ITestAutofac _autofac;
        private readonly ILogger<WSKController> _logger;
        private readonly IRedisManage _redis;
        private readonly IHttpClientHelper _httpClient;
        private readonly IHttpWebRequestHelper _httpWebRequestHelper;
        public WSKController(ITestAutofac autofac, ILogger<WSKController> logger, IRedisManage redis, IHttpClientHelper httpClient, IHttpWebRequestHelper httpWebRequestHelper) {
            _autofac = autofac;
            _logger = logger;
            _redis = redis;
            _httpClient = httpClient;
            _httpWebRequestHelper = httpWebRequestHelper;
        }
        [HttpPost]
        public IActionResult HelloWorld(string url1,string url2)
        {
            TestWebHelperInfo info = new TestWebHelperInfo();
            info.name = "Hello";
            var value1 = _httpClient.Post<TestWebHelperInfo>(url1,JsonConvert.SerializeObject(info));
            info.name = "World";
            var value2 = _httpWebRequestHelper.Request<TestWebHelperInfo>(url2, JsonConvert.SerializeObject(info));
            return Ok($"value1:{value1.name} value2:{value2.name}");
        }
        [HttpPost]
        public IActionResult Test1([FromBody] TestWebHelperInfo info)
        {
            return Ok(info);
        }
        [HttpPost]
        public IActionResult Test2([FromBody] TestWebHelperInfo info)
        {
            return Ok(info);
        }
    }
运行,然后测试一下1和2接口是否可以使用,如果可以使用,拷贝对应的url地址,当作参数传给主测试api里面。

获得到请求的url地址前缀是:http://localhost:35678/WSK/,带入参数进行验证:

由此可见,两个通用方法都可用。
备注:如果不适用泛型,也可以直接使用返回String即可,不需要进行类型转换。
如果觉得有用,欢迎点赞、评论、推荐或打赏~~
十二、.net core(.NET 6)添加通用的访问webapi的方法(包括HttpClient和HttpWebRequest)的更多相关文章
- 四十二、在SAP中添加单选框
		一.上代码 二.上文本替换截图 三.上效果图 
- Nginx详解十二:Nginx场景实践篇之跨站访问相关
		跨站访问 浏览器请求一个页面的时候,发送了两个域名的请求 此情况不安全,容易出现CSRF攻击,所以浏览器禁止跨域访问 Nginx设置打开跨站访问 配置语法:add_header name value ... 
- 第十二篇:随手记一下javaBean的setter,getter方法的命名问题
		今天测试新写的一个系统表的完整Ibatis配置和调用,因为经验少,到处撞墙...其他的坑爹问题就不提了 测试sqlMapClient.queryForList("...",para ... 
- .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
		本篇我将带着大家一起来对Dapper进行下封装并实现基本的增删改查.分页操作的同步异步方法的实现(已实现MSSQL,MySql,PgSQL).同时我们再实现一下仓储层的代码生成器,这样的话,我们只需要 ... 
- 如何在Visual Studio 2017中使用C# 7+语法    构建NetCore应用框架之实战篇(二):BitAdminCore框架定位及架构   构建NetCore应用框架之实战篇系列  构建NetCore应用框架之实战篇(一):什么是框架,如何设计一个框架  NetCore入门篇:(十二)在IIS中部署Net Core程序
		如何在Visual Studio 2017中使用C# 7+语法 前言 之前不知看过哪位前辈的博文有点印象C# 7控制台开始支持执行异步方法,然后闲来无事,搞着,搞着没搞出来,然后就写了这篇博文,不 ... 
- abp(net core)+easyui+efcore实现仓储管理系统——EasyUI之货物管理四 (二十二)
		abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ... 
- abp(net core)+easyui+efcore实现仓储管理系统——入库管理之六(四十二)
		abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ... 
- abp(net core)+easyui+efcore实现仓储管理系统——入库管理之十二(四十八)
		abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ... 
- abp(net core)+easyui+efcore实现仓储管理系统——出库管理之三(五十二)
		abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统--ABP总体介绍(一) abp(net core)+ ... 
随机推荐
- Java JFR 民间指南 - 事件详解 - jdk.ObjectAllocationOutsideTLAB
			重新申请 TLAB 分配对象事件:jdk.ObjectAllocationOutsideTLAB 引入版本:Java 11 相关 ISSUES: JFR: RecordingStream leaks ... 
- Linux在shell终端中清空DNS缓存,刷新DNS的方法
			现在很多Linux发行版都没有内置DNS本地缓存,Linux不像Windows那样可以使用ipconfig /flushdns来刷新,在Linux下无需刷新,因为本身没有缓存. 前言 在Linux系统 ... 
- Python 使用oslo.vmware管理ESXI虚拟机
			oslo.vmware是OpenStack通用框架中的一部分,主要用于实现对虚拟机的管理任务,借助oslo.vmware模块我们可以管理Vmware ESXI集群环境. 读取所有节点主机 from o ... 
- 通过中转DLL函数实现DLL劫持
			当我们运行程序时,一般情况下会默认加载Ntdll.dll和Kernel32.dll这两个链接库,在进程未被创建之前Ntdll.dll库就被默认加载了,三环下任何对其劫持都是无效的,除了该Dll外,其他 ... 
- hdu1287 破译密码
			题意: 破译密码 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ... 
- hdu1074 状态压缩dp+记录方案
			题意: 给你一些作业,每个作业有自己的结束时间和花费时间,如果超过结束时间完成,一天扣一分,问你把n个作业完成最少的扣分,要求输出方案. 思路: 状态压缩dp,记录方案数的地方 ... 
- 在 Peach 中使用发布者进行调试
			0x01 桃子平台 桃子平台(Peach)是一款流行的 Fuzz 平台,主要用作二进制文件及网络协议的模糊测试.其原理遵循基本的模糊测试流程,比较有特色的是它依赖用户所编写的 Pit 文件,同时输入的 ... 
- Debuggee not connected 寒江孤钓<<windows 内核安全编程>> 学习笔记
			双机联调出现的问题 真机系统win7 虚拟机系统xp 安装书中的配置一步一步走,发现最后启动系统后,windbg一直显示 Opened \\.\pipe\com_1Waiting to reconne ... 
- 『政善治』Postman工具 — 7、Postman中保存请求(Collections集合)
			目录 1.创建Collection 2.保存Request请求 3.查看保存的请求 4.Collection下还可以创建文件夹 5.补充:Postman中的变量 6.总结 1.创建Collection ... 
- 初识ClickHouse——安装与入门
			前言: 久闻 ClickHouse 大名,一直没有去详细了解.近期看了下 ClickHouse 相关文档,决定安装体验下.想了解 ClickHouse 的小伙伴可以一起跟着学习哦.本篇文章主要介绍 C ... 
