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; }
}
public class X2ServerResult
{
public const string Ok = "Ok";
public string Result { get; set; }
public string Msg { 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,bool isLog = true)
{
if (isLog)
{
Log.Information($"开始请求 {url} 请求参数: {JsonConvert.SerializeObject(pars)}");
}
using (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();
if (isLog)
{
Log.Information($"请求 {url} 参数: {JsonConvert.SerializeObject(pars)} 结果: {result}");
}
return result;
}
}
public static async Task GetAsync(string url, Dictionary headers = null, Dictionary pars = null)
{
using (var client = new HttpClient())
{
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)
{
client.DefaultRequestHeaders.Add(k, v);
}
}
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 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
};
}
}
}
}