当前位置: 首页 > news >正文

关于C# HttpClient 的用法及相关问题的解决方法

关于C# HttpClient 的用法及相关问题的解决方法

  • 1、遇到的问题
    • ① 远程主机强迫关闭了一个现有的连接
    • ② POST请求某种情况下请求会失败的解决方案
  • 2、使用HttpClient为什么建议使用单例
  • 3、基础代码实现

1、遇到的问题

① 远程主机强迫关闭了一个现有的连接

相信大家在使用 HttpClient 的时候遇到过 远程主机强迫关闭了一个现有的连接 的错误,一般的解决方法就是下面这种

解决办法:在请求方法中指定 ServicePoint 安全协议
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12;

② POST请求某种情况下请求会失败的解决方案

工作中遇到写正常的 http post 请求会失败的问题,于是就在原有的基础上改动了写代码使用HttpRequestMessage 指定 标头、HTTP 谓词和潜在数据,详情见代码第二个 post 请求方法。

2、使用HttpClient为什么建议使用单例

HttpClient 旨在被实例化一次并在应用程序的整个生命周期中重复使用。为每个请求实例化一个 HttpClient 类将耗尽重负载下可用的套接字数量。将导致 SocketException 错误

3、基础代码实现

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;

namespace Clear.DataServices.HttpHelper
{
    public class HttpClientService
    {
        private static HttpClientService _instance;

        private static readonly object _lock = new object();
        
        public HttpClientService() { }
        
        public static HttpClientService GetInstance()
        {
            if (_instance == null)
            {
                lock (_lock)
                {
                    if (_instance == null)
                    {
                        _instance = new HttpClientService();
                    }
                }
            }
            return _instance;
        }
      
        /// <summary>
        /// HttpClient Get请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <returns></returns>
        public string HttpGet(string url)
        {
            try
            {
                using (
                    HttpClient client = new HttpClient
                    {
                        BaseAddress = new Uri(url)
                    })
                {
                    client.DefaultRequestHeaders.Accept.Clear();
                    HttpResponseMessage response = client.GetAsync(url).Result;

                    response.EnsureSuccessStatusCode();
                    string responseBody = response.Content.ReadAsStringAsync().Result;

                    return responseBody;
                }
            }
            catch (Exception e)
            {                
                return e.Message;
            }
        }

        /// <summary>
        /// HttpClient Post请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="content">HttpContent</param>
        /// <returns></returns>
        public string HttpPost(string url, string content, string token = null)
        {
            try
            {
                using (
                    HttpClient client = new HttpClient
                    {
                        BaseAddress = new Uri(url)
                    })
                {
                    // System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12;

                    client.DefaultRequestHeaders.Accept.Clear();
                    client.DefaultRequestHeaders.Connection.Add("keep-alive");
                    if (!token.IsNullOrEmpty())
                    {
                        client.DefaultRequestHeaders.Add("Authorization-Token", token);
                    }
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
             
                    HttpResponseMessage response = client.PostAsync(url, new StringContent(content, Encoding.UTF8, "application/json")).Result;
                    response.EnsureSuccessStatusCode();
                    string responseBody = response.Content.ReadAsStringAsync().Result;
             
                    return responseBody;
                }
            }
            catch (Exception e)
            {                
                return e.Message;
            }
        }

        /// <summary>
        /// HttpClient Post请求
        /// </summary>
        /// <remarks>
        /// 用于非正常http请求
        /// </remarks>
        /// <param name="url"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public string HttpPost(string url, string content)
        {
            try
            {
                using (var httpClient = new HttpClient())
                {
                    using (var request = new HttpRequestMessage(new HttpMethod("Post"), url))
                    {
                        // System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12;

                        request.Headers.TryAddWithoutValidation("Content-Type", "application/json");

                        request.Content = new StringContent(content);

                        request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
                        var response = httpClient.SendAsync(request).Result;
                        return response.Content.ReadAsStringAsync().Result;
                    }
                }
            }
            catch (Exception e)
            {
                return e.Message;
            }
        }

        /// <summary>
        /// Model对象转换为uri网址参数形式
        /// </summary>
        /// <param name="obj">Model对象</param>
        /// <param name="url">前部分网址</param>
        /// <returns></returns>
        public string GetUriParam(object obj, string url = "")
        {
            PropertyInfo[] propertis = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
            StringBuilder sb = new StringBuilder();
            sb.Append(url);
            sb.Append("?");
            foreach (var p in propertis)
            {
                var v = p.GetValue(obj, null);
                if (v == null) continue;

                sb.Append(p.Name);
                sb.Append("=");
                sb.Append(Uri.EscapeDataString(v.ToString()));//将字符串转换为它的转义表示形式,HttpUtility.UrlEncode是小写
                sb.Append("&");
            }
            sb.Remove(sb.Length - 1, 1);

            return sb.ToString();
        }
    }
}

相关文章:

  • illustrator插件-什么是脚本-如何使用-什么是动作-AI插件
  • UVA 10405【LCS】【背包】
  • Git学习总结
  • Java项目:SSM医药信息管理系统
  • python——装饰器深入研究(一)
  • 猿创征文|【C++游戏引擎Easy2D】炫酷动画来这学,位移动画构造函数让节点执行动画
  • 做好规划 拿下未来!
  • MATLAB算法实战应用案例精讲-【智能优化算法】非支配排序遗传算法-NSGA-Ⅱ(附python和matlab代码)
  • 完美免费在线去背景图片,便捷变速。在5秒内消除或者替换图像背景,智能调整颜色,所有操作都在浏览器完成,无需上传图像 - BgSub
  • 一文掌握MySQL的索引(认真排版、简洁易懂)
  • 十、mongodb分片集群运维相关
  • 每日十(?)题之20220903
  • 2.数据结构与算法 进阶知识
  • 下载JDK8 JVM源码
  • 基于某钉探索针对CEF框架的一些逆向思路
  • 时间复杂度分析经典问题——最大子序列和
  • Android Volley源码解析
  • Fabric架构演变之路
  • Java Agent 学习笔记
  • JDK 6和JDK 7中的substring()方法
  • Linux链接文件
  • Material Design
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • Python中eval与exec的使用及区别
  • React中的“虫洞”——Context
  • Theano - 导数
  • Vue官网教程学习过程中值得记录的一些事情
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 从0到1:PostCSS 插件开发最佳实践
  • 跨域
  • 前端面试之闭包
  • 巧用 TypeScript (一)
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 小程序开发之路(一)
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 在Mac OS X上安装 Ruby运行环境
  • 自动记录MySQL慢查询快照脚本
  • 最简单的无缝轮播
  • 移动端高清、多屏适配方案
  • 正则表达式-基础知识Review
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ###项目技术发展史
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (10)ATF MMU转换表
  • (C语言)字符分类函数
  • (Matlab)使用竞争神经网络实现数据聚类
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (汇总)os模块以及shutil模块对文件的操作
  • (正则)提取页面里的img标签
  • *Django中的Ajax 纯js的书写样式1
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .net 怎么循环得到数组里的值_关于js数组
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • .php文件都打不开,打不开php文件怎么办