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

 更新时间:2022年11月18日 11:23:39   作者:黑夜中的潜行者  
相信大家在使用 HttpClient 的时候遇到过 远程主机强迫关闭了一个现有的连接 的错误。本文就来说说它的解决方法以及HttpClient的正确用法,需要的可以参考一下

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();
        
        private static HttpClient _client;
        
        public HttpClientService() { }
        
        public static HttpClientService GetInstance()
        {
            if (_instance == null)
            {
                lock (_lock)
                {
                    if (_instance == null)
                    {
                        _instance = new HttpClientService();
                    }
                    
                    if (_client is null)
					{
					    _client = new HttpClient();
					}
                }
            }
            return _instance;
        }
      
        /// <summary>
        /// HttpClient Get请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <returns></returns>
        public string HttpGet(string url)
        {
            try
            {
                if (_client.BaseAddress is null)
				{
				    _client.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)
            {                
                object errorMessage = new
                {
                    code = "-1",
                    message = e.Message
                };
                return JsonConvert.SerializeObject(errorMessage);
            }
        }

        /// <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
            {
                if (_client.BaseAddress is null)
				{
				    _client.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)
            {                
                object errorMessage = new
                {
                    code = "-1",
                    message = e.Message
                };
                return JsonConvert.SerializeObject(errorMessage);
            }
        }

        /// <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 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 = _client.SendAsync(request).Result;
                    return response.Content.ReadAsStringAsync().Result;
                }
            }
            catch (Exception e)
            {
                object errorMessage = new
                {
                    code = "-1",
                    message = e.Message
                };
                return JsonConvert.SerializeObject(errorMessage);
            }
        }

        /// <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();
        }
    }
}

到此这篇关于详解C#中HttpClient的用法及相关问题的解决方法的文章就介绍到这了,更多相关C# HttpClient内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解C# wpf如何嵌入hwnd窗口

    详解C# wpf如何嵌入hwnd窗口

    wpf是Direct UI,窗口中只有一个hwnd句柄,大部分控件都是直接在上面绘制的,本文主要来和大家讲讲如何嵌入hwnd窗口,感兴趣的可以了解一下
    2024-03-03
  • C#实现将json转换为DataTable的方法

    C#实现将json转换为DataTable的方法

    这篇文章主要介绍了C#实现将json转换为DataTable的方法,涉及C#操作json及DataTable的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • C#使用正则表达式隐藏手机号中间四位为*

    C#使用正则表达式隐藏手机号中间四位为*

    这篇文章主要介绍了C#使用正则表达式隐藏手机号中间四位为*的相关资料,需要的朋友可以参考下
    2017-06-06
  • C# 的关键字详细介绍

    C# 的关键字详细介绍

    本文将详细介绍C#关键字的应用,可供有需要的朋友参考
    2012-11-11
  • C#关联自定义文件类型到应用程序并实现自动导入功能

    C#关联自定义文件类型到应用程序并实现自动导入功能

    今天通过本文给大家分享C#关联自定义文件类型到应用程序并实现自动导入功能,代码中写入了两个注册表,实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2021-09-09
  • C# 字典Dictionary的具体用法

    C# 字典Dictionary的具体用法

    本文主要介绍了C# 字典Dictionary的具体用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • TortoiseSVN使用教程

    TortoiseSVN使用教程

    TortoiseSVN 是 Subversion 版本控制系统的一个免费开源客户端,可以超越时间的管理文件和目录。本文给大家介绍TortoiseSVN使用教程,对tortoisesvn使用相关知识感兴趣的朋友一起学习吧
    2015-12-12
  • C#判断单词个数方法总结

    C#判断单词个数方法总结

    我们给大家总计了C#中判断英文单词个数的方法以及排序的技巧,对此有需要的朋友可以测试下。
    2018-03-03
  • c#如何使用UDP进行聊天通信

    c#如何使用UDP进行聊天通信

    这篇文章主要介绍了c#如何使用UDP进行聊天通信问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • 在GridControl控件上绑定图片的几种操作方式详解

    在GridControl控件上绑定图片的几种操作方式详解

    GridControl控件是经常用来绑定数据的,一般以常规的字符内容为主,有时候也会有图片的显示需要,这篇文章主要介绍了在GridControl控件上绑定图片的几种操作方式详解,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07

最新评论