using System.Net.Http.Headers; using System.Text; using JNPF.Logging; using Microsoft.AspNetCore.WebUtilities; using Newtonsoft.Json; namespace Tnb.Common.Utils { public class ApiException : Exception { public int StatusCode { get; set; } public string Content { get; set; } } /// /// Http请求帮助类 /// added by ly on 20230801 /// public class HttpClientHelper { private static readonly HttpClient HttpClient = new HttpClient(); private static Dictionary HttpClientDict = new Dictionary(StringComparer.OrdinalIgnoreCase); public static string Url { get; private set; } public static async Task HttpPostAsync(string url, string clientKey, string postData = null, Dictionary headers = null, string contentType = "application/json", int timeOut = 30) { using var client = HttpClientDict[clientKey]; if (headers != null) { foreach (var header in headers) client.DefaultRequestHeaders.Add(header.Key, header.Value); } using HttpContent httpContent = new StringContent(postData, Encoding.UTF8); if (contentType != null) httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType); var response = await client.PostAsync(url, httpContent); return await response.Content.ReadAsStringAsync(); } /// /// 发起POST异步请求 /// /// /// /// application/xml、application/json、application/text、application/x-www-form-urlencoded /// 填充消息头 /// public static async Task HttpPostAsync(string url, string postData = null, Dictionary headers = null, string contentType = "application/json", int timeOut = 30) { postData ??= ""; HttpResponseMessage response = null; HttpClient client = null; try { if (client == null) client = new HttpClient(); //HttpClient.Timeout = new TimeSpan(0, 0, timeOut); if (headers != null) { foreach (var header in headers) client.DefaultRequestHeaders.Add(header.Key, header.Value); } //var request = new HttpRequestMessage(HttpMethod.Post, url); //request.Headers.Accept.Clear(); //request.Headers. using HttpContent httpContent = new StringContent(postData, Encoding.UTF8); if (contentType != null) httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType); response = await client.PostAsync(url, httpContent); } catch (Exception ex) { client = new HttpClient(); } return await response.Content.ReadAsStringAsync(); } public static async Task PostFormDataAsync(string url, Dictionary pars) { var respJson = ""; try { var content = new FormUrlEncodedContent(pars); var respBody = await HttpClient.PostAsync(url, content); respJson = await respBody.Content.ReadAsStringAsync(); } catch (Exception ex) { Log.Error("调用PostFormDataAsync时出错", ex); } return respJson; } public static async Task GetRequestAsync(string url, Dictionary pars = null) { HttpClient Client = new HttpClient(); var reqUri = url; if (pars?.Count > 0) { reqUri = QueryHelpers.AddQueryString(url, pars); //await Console.Out.WriteLineAsync(reqUri); } Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var respBody = await Client.GetAsync(reqUri); var result = await respBody.Content.ReadAsStringAsync(); return result; } public static async Task GetAsync(string url, Dictionary headers = null, Dictionary pars = null) { var reqUri = url; if (pars?.Count > 0) { reqUri = QueryHelpers.AddQueryString(url, pars); //await Console.Out.WriteLineAsync(reqUri); } if (headers?.Count > 0) { foreach (var (k, v) in headers) { HttpClient.DefaultRequestHeaders.Add(k, v); } } HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var respBody = await HttpClient.GetAsync(reqUri); var result = await respBody.Content.ReadAsStringAsync(); return result; } public static async Task PostStreamAsync(string url, object content, CancellationToken cancellationToken) { using (var client = new HttpClient()) using (var request = new HttpRequestMessage(HttpMethod.Post, url)) using (var httpContent = CreateHttpContent(content)) { request.Content = httpContent; using (var response = await client .SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken) .ConfigureAwait(false)) { response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); } } } private static HttpContent CreateHttpContent(object content) { HttpContent httpContent = null; if (content != null) { var ms = new MemoryStream(); SerializeJsonIntoStream(content, ms); ms.Seek(0, SeekOrigin.Begin); httpContent = new StreamContent(ms); httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } return httpContent; } public static void SerializeJsonIntoStream(object value, Stream stream) { using (var sw = new StreamWriter(stream, new UTF8Encoding(false), 1024, true)) using (var jtw = new JsonTextWriter(sw) { Formatting = Formatting.None }) { var js = new JsonSerializer(); js.Serialize(jtw, value); jtw.Flush(); } } private static T DeserializeJsonFromStream(Stream stream) { if (stream == null || stream.CanRead == false) return default(T); using (var sr = new StreamReader(stream)) using (var jtr = new JsonTextReader(sr)) { var js = new JsonSerializer(); var searchResult = js.Deserialize(jtr); return searchResult; } } private static async Task StreamToStringAsync(Stream stream) { string content = null; if (stream != null) using (var sr = new StreamReader(stream)) content = await sr.ReadToEndAsync(); return content; } private static async Task> DeserializeFromStreamCallAsync(CancellationToken cancellationToken) { using (var client = new HttpClient()) using (var request = new HttpRequestMessage(HttpMethod.Get, Url)) using (var response = await client.SendAsync(request, cancellationToken)) { var stream = await response.Content.ReadAsStreamAsync(); if (response.IsSuccessStatusCode) return DeserializeJsonFromStream>(stream); var content = await StreamToStringAsync(stream); throw new ApiException { StatusCode = (int)response.StatusCode, Content = content }; } } private static async Task> DeserializeOptimizedFromStreamCallAsync(CancellationToken cancellationToken) { using (var client = new HttpClient()) using (var request = new HttpRequestMessage(HttpMethod.Get, Url)) using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken)) { var stream = await response.Content.ReadAsStreamAsync(); if (response.IsSuccessStatusCode) return DeserializeJsonFromStream>(stream); var content = await StreamToStringAsync(stream); throw new ApiException { StatusCode = (int)response.StatusCode, Content = content }; } } } }