首页 > 编程语言 >关于C# HttpClient 的用法及相关问题的解决方法

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

时间:2023-01-31 15:03:33浏览次数:108  
标签:string C# System 用法 client new Net 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();

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


标签:string,C#,System,用法,client,new,Net,HttpClient
From: https://blog.51cto.com/u_14316538/6029338

相关文章

  • C#文件转byte[]再将byte[]转文件
    将文件转为byte[]然后再将byte[]转成文件,这本是没什么难度的事,可是很多人在做将文件转为byte[]时很容易忽略​​fs.Read(buffur,0,(int)buffur.Length);​​语句导致byt......
  • FLASH-CH32F203替换STM32F103 FLASH快速编程移植说明
    因CH32F203相对于STM32flash操作多了快速编程模式,该文档说明主要目的是为了方便客户在原先ST工程的基础上实现flash快速编程模式的快速移植。1、在stm32f10x.h文件......
  • Pytorch_YOLO
    历史版本2016年,JosephRedmon提出了他至今以来最有名的个人项目:JosephRedmon《YouOnlyLookOnce:Unified,Real-TimeObjectDetection》 https://pjreddie.co......
  • PostgreSQL学习笔记-3.基础知识:CROSS、INNER、LEFT OUTER、RIGHT OUTER、FULL OUTER、
    PostgreSQLJOIN子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段。在PostgreSQL中,JOIN有五种连接类型:CROSSJOIN:交叉连接INNERJOIN:内连接LEFTOU......
  • FLASH-CH32F203替换CH32F103 FLASH快速编程移植说明
    因CH32F203相对于CH32F103flash操作的快速编程模式由单次128字节编程变成了单次256字节编程,该文档说明主要目的是为了方便客户在原先CH32F103工程的基础上实现flash单次......
  • C2驾驶车型
    凡是自动挡的9座(包括9座)以下,车长6米以内的小型载客汽车(包含轿车、SUV、MPV);以及总质量在4500KG(包括4500KG)以下的、车长在6米(包括6米)以下的、核定载重质量在1500KG(包括1500KG......
  • 导入ElasticSearch官方测试数据
    学习ES的过程中,苦于测试数据不全,手动插入数据速度太慢,后来发现ES官方提供了一些测试数据可以直接导入到自建的ES,但是由于官方文档的没有更新,导入过程中会报错,具体原因是E......
  • FLASH-CH32F103替换STM32F103 FLASH快速编程说明
    因CH32F103相对于STM32F103flash操作多了快速编程模式,该文档说明主要目的是为了方便客户在原先ST工程的基础上实现flash快速编程模式的快速移植。1、在stm32f10x.h......
  • Back Up and Restore of SQL Server Databases
    Skiptomaincontent  LearnDocumentationTrainingCertificationsQ&ACodeSamplesAssessmentsShowsEventsSigninSQLDocsOverviewInstallS......
  • JNDI学习总结(三):tomcat下使用c3p0数据库连接池配置JNDI数据源
    tomcat是apache的,所以它的JNDI数据源默认使用commons组件的DBCP连接池来配置。如果想使用c3p0来配置数据源,就需要修改<Resource>标签里的部分配置选项,操作如下: 1.肯定......