You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

460 lines
19KB

  1. using Microsoft.Extensions.Logging;
  2. using Newtonsoft.Json;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Net.Http;
  6. using System.Net.Http.Headers;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace TelpoPush.Common
  10. {
  11. /// <summary>
  12. /// HTTP帮助类
  13. /// </summary>
  14. public class HttpHelperAsync
  15. {
  16. private IHttpClientFactory _httpClientFactory;
  17. private readonly ILogger<HttpHelperAsync> _logger;
  18. public HttpHelperAsync(IHttpClientFactory httpClientFactory, ILogger<HttpHelperAsync> logger)
  19. {
  20. _httpClientFactory = httpClientFactory;
  21. _logger = logger;
  22. }
  23. #region 异步
  24. /// <summary>
  25. /// 发起POST异步请求表单
  26. /// </summary>
  27. /// <param name="url">请求地址</param>
  28. /// <param name="body">POST提交的内容</param>
  29. /// <param name="bodyMediaType">POST内容的媒体类型,如:application/xml、application/json</param>
  30. /// <param name="responseContentType">HTTP响应上的content-type内容头的值,如:application/xml、application/json、application/text、application/x-www-form-urlencoded等</param>
  31. /// <param name="headers">请求头信息</param>
  32. /// <param name="timeOut">请求超时时间,单位秒</param>
  33. /// <returns>返回string</returns>
  34. public async Task<string> PostFormAsync(string url, MultipartFormDataContent content,
  35. Dictionary<string, string> headers = null,
  36. int timeOut = 5)
  37. {
  38. try
  39. {
  40. var hostName = GetHostName(url);
  41. using (HttpClient client = _httpClientFactory.CreateClient(hostName))
  42. {
  43. client.Timeout = TimeSpan.FromSeconds(timeOut);
  44. if (headers?.Count > 0)
  45. {
  46. foreach (string key in headers.Keys)
  47. {
  48. client.DefaultRequestHeaders.Add(key, headers[key]);
  49. }
  50. }
  51. content.Headers.Add("ContentType", "multipart/form-data");//声明头部
  52. using (HttpResponseMessage response = await client.PostAsync(url, content))
  53. {
  54. return JsonConvert.SerializeObject(new { response.IsSuccessStatusCode, response.StatusCode });
  55. //if (response.IsSuccessStatusCode)
  56. //{
  57. // string responseString = await response.Content.ReadAsStringAsync();
  58. // return responseString;
  59. //}
  60. //else
  61. //{
  62. // return string.Empty;
  63. //}
  64. }
  65. }
  66. }
  67. catch (Exception ex)
  68. {
  69. return $"推送完成:请求响应超过{timeOut}秒,异常 {ex.Message}";
  70. }
  71. }
  72. /// <summary>
  73. /// 发起GET异步请求
  74. /// </summary>
  75. /// <typeparam name="T">返回类型</typeparam>
  76. /// <param name="url">请求地址</param>
  77. /// <param name="headers">请求头信息</param>
  78. /// <param name="timeOut">请求超时时间,单位秒</param>
  79. /// <returns>返回string</returns>
  80. public async Task<string> GetAsync(string url, Dictionary<string, string> headers = null, int timeOut = 30)
  81. {
  82. var hostName = GetHostName(url);
  83. using (HttpClient client = _httpClientFactory.CreateClient(hostName))
  84. {
  85. client.Timeout = TimeSpan.FromSeconds(timeOut);
  86. if (headers?.Count > 0)
  87. {
  88. foreach (string key in headers.Keys)
  89. {
  90. client.DefaultRequestHeaders.Add(key, headers[key]);
  91. }
  92. }
  93. using (HttpResponseMessage response = await client.GetAsync(url))
  94. {
  95. if (response.IsSuccessStatusCode)
  96. {
  97. string responseString = await response.Content.ReadAsStringAsync();
  98. return responseString;
  99. }
  100. else
  101. {
  102. return string.Empty;
  103. }
  104. }
  105. }
  106. }
  107. /// <summary>
  108. /// 发起POST异步请求
  109. /// </summary>
  110. /// <param name="url">请求地址</param>
  111. /// <param name="body">POST提交的内容</param>
  112. /// <param name="bodyMediaType">POST内容的媒体类型,如:application/xml、application/json</param>
  113. /// <param name="responseContentType">HTTP响应上的content-type内容头的值,如:application/xml、application/json、application/text、application/x-www-form-urlencoded等</param>
  114. /// <param name="headers">请求头信息</param>
  115. /// <param name="timeOut">请求超时时间,单位秒</param>
  116. /// <returns>返回string</returns>
  117. public async Task<string> PostAsync(string url, string body,
  118. Dictionary<string, string> headers = null,
  119. int timeOut = 30,
  120. string bodyMediaType = "application/json",
  121. string responseContentType = "application/json;charset=utf-8")
  122. {
  123. //content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  124. //var clientHandler = new HttpClientHandler
  125. //{
  126. // ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true
  127. //};
  128. //using (var client = new HttpClient(clientHandler))
  129. //{
  130. // client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
  131. try
  132. {
  133. var hostName = GetHostName(url);
  134. using (HttpClient client = _httpClientFactory.CreateClient(hostName))
  135. {
  136. client.Timeout = TimeSpan.FromSeconds(timeOut);
  137. if (headers?.Count > 0)
  138. {
  139. foreach (string key in headers.Keys)
  140. {
  141. client.DefaultRequestHeaders.Add(key, headers[key]);
  142. }
  143. }
  144. StringContent content = new StringContent(body, System.Text.Encoding.UTF8, mediaType: bodyMediaType);
  145. if (!string.IsNullOrWhiteSpace(responseContentType))
  146. {
  147. content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(responseContentType);
  148. }
  149. using (HttpResponseMessage response = await client.PostAsync(url, content))
  150. {
  151. if (response.IsSuccessStatusCode)
  152. {
  153. string responseString = await response.Content.ReadAsStringAsync();
  154. return responseString;
  155. }
  156. else
  157. return $"请求异常:{response.IsSuccessStatusCode},{response.StatusCode}";
  158. }
  159. }
  160. }
  161. catch(Exception ex)
  162. {
  163. return $"请求异常:{ex.Message}";
  164. }
  165. }
  166. /// <summary>
  167. /// 发起POST异步请求
  168. /// </summary>
  169. /// <param name="url">请求地址</param>
  170. /// <param name="body">POST提交的内容</param>
  171. /// <param name="bodyMediaType">POST内容的媒体类型,如:application/xml、application/json</param>
  172. /// <param name="responseContentType">HTTP响应上的content-type内容头的值,如:application/xml、application/json、application/text、application/x-www-form-urlencoded等</param>
  173. /// <param name="headers">请求头信息</param>
  174. /// <param name="timeOut">请求超时时间,单位秒</param>
  175. /// <returns>返回string</returns>
  176. public async Task<string> PutAsync(string url, string body,
  177. string bodyMediaType = null,
  178. string responseContentType = null,
  179. Dictionary<string, string> headers = null,
  180. int timeOut = 30)
  181. {
  182. var hostName = GetHostName(url);
  183. using (HttpClient client = _httpClientFactory.CreateClient(hostName))
  184. {
  185. client.Timeout = TimeSpan.FromSeconds(timeOut);
  186. if (headers?.Count > 0)
  187. {
  188. foreach (string key in headers.Keys)
  189. {
  190. client.DefaultRequestHeaders.Add(key, headers[key]);
  191. }
  192. }
  193. StringContent content = new StringContent(body, System.Text.Encoding.UTF8, mediaType: bodyMediaType);
  194. if (!string.IsNullOrWhiteSpace(responseContentType))
  195. {
  196. content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(responseContentType);
  197. }
  198. using (HttpResponseMessage response = await client.PutAsync(url, content))
  199. {
  200. if (response.IsSuccessStatusCode)
  201. {
  202. string responseString = await response.Content.ReadAsStringAsync();
  203. return responseString;
  204. }
  205. else
  206. {
  207. return string.Empty;
  208. }
  209. }
  210. }
  211. }
  212. /// <summary>
  213. /// 发起GET异步请求
  214. /// </summary>
  215. /// <typeparam name="T">返回类型</typeparam>
  216. /// <param name="url">请求地址</param>
  217. /// <param name="headers">请求头信息</param>
  218. /// <param name="timeOut">请求超时时间,单位秒</param>
  219. /// <returns>返回string</returns>
  220. public async Task<string> DeleteAsync(string url, Dictionary<string, string> headers = null, int timeOut = 30)
  221. {
  222. var hostName = GetHostName(url);
  223. using (HttpClient client = _httpClientFactory.CreateClient(hostName))
  224. {
  225. client.Timeout = TimeSpan.FromSeconds(timeOut);
  226. if (headers?.Count > 0)
  227. {
  228. foreach (string key in headers.Keys)
  229. {
  230. client.DefaultRequestHeaders.Add(key, headers[key]);
  231. }
  232. }
  233. using (HttpResponseMessage response = await client.DeleteAsync(url))
  234. {
  235. if (response.IsSuccessStatusCode)
  236. {
  237. string responseString = await response.Content.ReadAsStringAsync();
  238. return responseString;
  239. }
  240. else
  241. {
  242. return string.Empty;
  243. }
  244. }
  245. }
  246. }
  247. /// <summary>
  248. /// 发起GET异步请求
  249. /// </summary>
  250. /// <typeparam name="T">返回类型</typeparam>
  251. /// <param name="url">请求地址</param>
  252. /// <param name="headers">请求头信息</param>
  253. /// <param name="timeOut">请求超时时间,单位秒</param>
  254. /// <returns>返回T</returns>
  255. public async Task<T> GetAsync<T>(string url, Dictionary<string, string> headers = null, int timeOut = 30) where T : new()
  256. {
  257. string responseString = await GetAsync(url, headers, timeOut);
  258. if (!string.IsNullOrWhiteSpace(responseString))
  259. {
  260. return JsonConvert.DeserializeObject<T>(responseString);
  261. }
  262. else
  263. {
  264. return default(T);
  265. }
  266. }
  267. /// <summary>
  268. /// 发起POST异步请求
  269. /// </summary>
  270. /// <typeparam name="T">返回类型</typeparam>
  271. /// <param name="url">请求地址</param>
  272. /// <param name="body">POST提交的内容</param>
  273. /// <param name="bodyMediaType">POST内容的媒体类型,如:application/xml、application/json</param>
  274. /// <param name="responseContentType">HTTP响应上的content-type内容头的值,如:application/xml、application/json、application/text、application/x-www-form-urlencoded等</param>
  275. /// <param name="headers">请求头信息</param>
  276. /// <param name="timeOut">请求超时时间,单位秒</param>
  277. /// <returns>返回T</returns>
  278. public async Task<T> PostAsync<T>(string url, string body,
  279. Dictionary<string, string> headers = null,
  280. int timeOut = 30,
  281. string bodyMediaType = "application/json",
  282. string responseContentType = "application/json;charset=utf-8"
  283. ) where T : new()
  284. {
  285. string responseString = await PostAsync(url, body, headers, timeOut, bodyMediaType, responseContentType);
  286. if (!string.IsNullOrWhiteSpace(responseString))
  287. {
  288. return JsonConvert.DeserializeObject<T>(responseString);
  289. }
  290. else
  291. {
  292. return default(T);
  293. }
  294. }
  295. /// <summary>
  296. /// 发起PUT异步请求
  297. /// </summary>
  298. /// <typeparam name="T">返回类型</typeparam>
  299. /// <param name="url">请求地址</param>
  300. /// <param name="body">POST提交的内容</param>
  301. /// <param name="bodyMediaType">POST内容的媒体类型,如:application/xml、application/json</param>
  302. /// <param name="responseContentType">HTTP响应上的content-type内容头的值,如:application/xml、application/json、application/text、application/x-www-form-urlencoded等</param>
  303. /// <param name="headers">请求头信息</param>
  304. /// <param name="timeOut">请求超时时间,单位秒</param>
  305. /// <returns>返回T</returns>
  306. public async Task<T> PutAsync<T>(string url, string body,
  307. string bodyMediaType = null,
  308. string responseContentType = null,
  309. Dictionary<string, string> headers = null,
  310. int timeOut = 30) where T : new()
  311. {
  312. string responseString = await PutAsync(url, body, bodyMediaType, responseContentType, headers, timeOut);
  313. if (!string.IsNullOrWhiteSpace(responseString))
  314. {
  315. return JsonConvert.DeserializeObject<T>(responseString);
  316. }
  317. else
  318. {
  319. return default(T);
  320. }
  321. }
  322. /// <summary>
  323. /// 发起DELETE异步请求
  324. /// </summary>
  325. /// <typeparam name="T">返回类型</typeparam>
  326. /// <param name="url">请求地址</param>
  327. /// <param name="headers">请求头信息</param>
  328. /// <param name="timeOut">请求超时时间,单位秒</param>
  329. /// <returns>返回T</returns>
  330. public async Task<T> DeleteAsync<T>(string url, Dictionary<string, string> headers = null, int timeOut = 30) where T : new()
  331. {
  332. string responseString = await DeleteAsync(url, headers, timeOut);
  333. if (!string.IsNullOrWhiteSpace(responseString))
  334. {
  335. return JsonConvert.DeserializeObject<T>(responseString);
  336. }
  337. else
  338. {
  339. return default(T);
  340. }
  341. }
  342. #region 私有函数
  343. /// <summary>
  344. /// 获取请求的主机名
  345. /// </summary>
  346. /// <param name="url"></param>
  347. /// <returns></returns>
  348. private static string GetHostName(string url)
  349. {
  350. if (!string.IsNullOrWhiteSpace(url))
  351. {
  352. return url.Replace("https://", "").Replace("http://", "").Split('/')[0];
  353. }
  354. else
  355. {
  356. return "AnyHost";
  357. }
  358. }
  359. #endregion
  360. #endregion
  361. #region 同步
  362. /// <summary>
  363. /// 发起GET同步请求
  364. /// </summary>
  365. /// <param name="url"></param>
  366. /// <param name="headers"></param>
  367. /// <param name="contentType"></param>
  368. /// <returns></returns>
  369. ///
  370. public string HttpGet(string url, Dictionary<string, string> headers = null, string contentType = "application/json;charset=utf-8")
  371. {
  372. if (string.IsNullOrEmpty(url)) return "";
  373. try
  374. {
  375. using (HttpClient client = new HttpClient())
  376. {
  377. if (contentType != null)
  378. client.DefaultRequestHeaders.Add("ContentType", contentType);
  379. if (headers != null)
  380. {
  381. foreach (var header in headers)
  382. client.DefaultRequestHeaders.Add(header.Key, header.Value);
  383. }
  384. HttpResponseMessage response = client.GetAsync(url).Result;
  385. return response.Content.ReadAsStringAsync().Result;
  386. }
  387. }
  388. catch (Exception ex)
  389. {
  390. _logger.LogDebug($"HttpGet/URL:{url},headers:{JsonConvert.SerializeObject(headers)},异常:{ex.Message}|{ex.Source}|{ex.StackTrace}");
  391. }
  392. return "";
  393. }
  394. /// <summary>
  395. /// 发起POST同步请求
  396. /// </summary>
  397. /// <param name="url"></param>
  398. /// <param name="postData"></param>
  399. /// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
  400. /// <param name="headers">填充消息头</param>
  401. /// <returns></returns>
  402. public string HttpPost(string url, string postData = null, Dictionary<string, string> headers = null, string contentType = "application/json")
  403. {
  404. if (string.IsNullOrEmpty(url)) return "";
  405. try
  406. {
  407. postData = postData ?? "";
  408. using (HttpClient client = new HttpClient())
  409. {
  410. if (headers != null)
  411. {
  412. foreach (var header in headers)
  413. client.DefaultRequestHeaders.Add(header.Key, header.Value);
  414. }
  415. using (HttpContent httpContent = new StringContent(postData, Encoding.UTF8))
  416. {
  417. if (contentType != null)
  418. httpContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
  419. HttpResponseMessage response = client.PostAsync(url, httpContent).Result;
  420. return response.Content.ReadAsStringAsync().Result;
  421. }
  422. }
  423. }
  424. catch (Exception ex){
  425. _logger.LogDebug($"HttpPost/URL:{url},postStr:{postData},headers:{JsonConvert.SerializeObject(headers)},异常:{ex.Message}|{ex.Source}|{ex.StackTrace}");
  426. }
  427. return "";
  428. }
  429. #endregion
  430. }
  431. }