详解C#中HttpClient的用法及相关问题的解决方法
黑夜中的潜行者 人气:01、遇到的问题
① 远程主机强迫关闭了一个现有的连接
相信大家在使用 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(); } } }
加载全部内容