using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Security.Cryptography; using System.Text; using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.Unicode; using System.Threading.Tasks; using System.Web; namespace DG.Core { public class HttpClient : IHttpClient { private readonly IHttpClientFactory _httpClientFactory; private readonly ILogger _logger; private static LogLevel _logLevel = LogLevel.Debug; public HttpClient(IHttpClientFactory httpClientFactory, ILogger logger) { _httpClientFactory = httpClientFactory; _logger = logger; } private static JsonSerializerOptions options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }; public void ChangeLogLevel(LogLevel logLevel) { _logLevel = logLevel; } private void Log(string message) { _logger.Log(_logLevel, message); } /// /// Post Security /// /// /// /// /// /// /// /// public async Task PostSecurityAsync(string url, object data, string clientid, string accessKey, string iv) { try { var timeStamp = GetTimeStamp(); var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true }; var param = JsonSerializer.Serialize(data, options); var bodyJson = EncryptByAES(param, accessKey, iv); var sign = SignData(bodyJson, accessKey); var client = _httpClientFactory.CreateClient(); client.DefaultRequestHeaders.TryAddWithoutValidation("clientid", clientid); client.DefaultRequestHeaders.Add("sign", sign); var httpData = new StringContent(bodyJson, Encoding.UTF8, "application/json"); Log($"POST 请求Url:{url}, Body:{bodyJson}"); var httpResponse = await client.PostAsync($"{url}", httpData); var stream = await httpResponse.Content.ReadAsStringAsync(); Log($"请求结果:{stream}"); var response = JsonSerializer.Deserialize(stream, options); return response; } catch (Exception ex) { _logger.LogError(ex, "POST 方法请求错误!"); throw; } } private static string SignData(string ciphertext, string accessKey) { Encoding utf = new UTF8Encoding(); HMACMD5 hmac = new HMACMD5(utf.GetBytes(accessKey)); byte[] hashValue = hmac.ComputeHash(utf.GetBytes(ciphertext)); return Convert.ToBase64String(hashValue); } /// /// /// /// /// /// /// /// /// /// public async Task PostSecurityAsync(string url, object param, object data, string clientid, string accessKey) { try { var timeStamp = GetTimeStamp(); var paramStr = JsonSerializer.Serialize(param, options); var bodyJson = JsonSerializer.Serialize(data, options); var content = EncyptData(paramStr, accessKey); var sign = SignData(content, accessKey); var client = _httpClientFactory.CreateClient(); client.Timeout = TimeSpan.FromSeconds(30); var httpData = new StringContent(bodyJson, Encoding.UTF8, "application/json"); url = $"{url}?content={HttpUtility.UrlEncode(content)}&sign={HttpUtility.UrlEncode(sign, Encoding.UTF8)}&clientid={clientid}"; Log($"POST 请求Url:{url}, Body:{bodyJson}"); var httpResponse = await client.PostAsync(url, httpData); var stream = await httpResponse.Content.ReadAsStringAsync(); Log($"请求结果:{stream}"); var response = JsonSerializer.Deserialize(stream, options); return response; } catch (Exception ex) { _logger.LogError(ex, "POST 方法请求错误!"); throw; } } /// /// Post Security /// /// /// /// /// /// /// /// public async Task PostSecurityAsync(string url, object data, string clientid, string accessKey, string iv) { try { var timeStamp = GetTimeStamp(); var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true }; var param = JsonSerializer.Serialize(data, options); var bodyJson = EncryptByAES(param, accessKey, iv); var sign = SignData(bodyJson, accessKey); var client = _httpClientFactory.CreateClient(); client.DefaultRequestHeaders.TryAddWithoutValidation("clientid", clientid); client.DefaultRequestHeaders.Add("sign", sign); var httpData = new StringContent(bodyJson, Encoding.UTF8, "application/json"); Log($"POST 请求Url:{url}, Body:{bodyJson}"); var httpResponse = await client.PostAsync($"{url}", httpData); var response = await httpResponse.Content.ReadAsStringAsync(); Log($"请求结果:{response}"); return response; } catch (Exception ex) { _logger.LogError(ex, "POST 方法请求错误!"); throw; } } /// /// /// /// /// /// /// /// /// /// public async Task PostSecurityAsync(string url, object param, object data, string clientid, string accessKey) { try { var timeStamp = GetTimeStamp(); var paramStr = JsonSerializer.Serialize(param, options); var bodyJson = JsonSerializer.Serialize(data, options); var content = EncyptData(paramStr, accessKey); var sign = SignData(content, accessKey); var client = _httpClientFactory.CreateClient(); var httpData = new StringContent(bodyJson, Encoding.UTF8, "application/json"); url = $"{url}?content={HttpUtility.UrlEncode(content)}&sign={HttpUtility.UrlEncode(sign, Encoding.UTF8)}&clientid={clientid}"; Log($"POST 请求Url:{url}, Body:{bodyJson}"); var httpResponse = await client.PostAsync(url, httpData); var response = await httpResponse.Content.ReadAsStringAsync(); Log($"请求结果:{response}"); return response; } catch (Exception ex) { _logger.LogError(ex, "POST 方法请求错误!"); throw; } } public async Task UploadFileAsync(string url, string fileName, string fullName, Dictionary? headers = null) { try { var buffer = await File.ReadAllBytesAsync(fullName); var client = _httpClientFactory.CreateClient(); if (headers != null) { foreach (var header in headers) { client.DefaultRequestHeaders.Add(header.Key, header.Value); } } ByteArrayContent fileContent = new ByteArrayContent(buffer); fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "file", FileName = fileName }; MultipartFormDataContent content = new MultipartFormDataContent { fileContent }; Log($"UploadFile 文件上传,请求Url:{url}"); var httpResponse = await client.PostAsync(url, content); var stream = await httpResponse.Content.ReadAsStringAsync(); Log($"请求结果:{stream}"); var response = JsonSerializer.Deserialize(stream, options); return response; } catch (Exception ex) { _logger.LogError(ex, "UploadFile 方法请求错误!"); throw; } } public async Task UploadFileAsync(string url, string fileName, string fullName, Dictionary? headers = null) { try { var buffer = await File.ReadAllBytesAsync(fullName); var client = _httpClientFactory.CreateClient(); if (headers != null) { foreach (var header in headers) { client.DefaultRequestHeaders.Add(header.Key, header.Value); } } ByteArrayContent fileContent = new ByteArrayContent(buffer); fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "file", FileName = fileName }; MultipartFormDataContent content = new MultipartFormDataContent { fileContent }; Log($"UploadFile 文件上传,请求Url:{url}"); var httpResponse = await client.PostAsync(url, content); var response = await httpResponse.Content.ReadAsStringAsync(); Log($"请求结果:{response}"); return response; } catch (Exception ex) { _logger.LogError(ex, "UploadFile 方法请求错误!"); throw; } } #region 正常请求 /// /// Post /// /// /// /// /// /// /// /// public async Task PostAsync2(string url, string data, string? appId = "", string? appSecret = "", string? mediaType = "application/json") { // _logger.LogInformation("卧槽,进来了。1111"); try { var client = _httpClientFactory.CreateClient(); //var options = new JsonSerializerOptions //{ // DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, // PropertyNameCaseInsensitive = true //}; // _logger.LogInformation("卧槽,进来了。"); var bodyJson = data; if (!string.IsNullOrEmpty(appId)) { client.DefaultRequestHeaders.Add("appid", appId); } if (!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appSecret)) { var timeStamp = GetTimeStamp(); var sign = CreateSign(appId, bodyJson, appSecret, timeStamp); var authorization = $"{appId}:{sign}"; client.DefaultRequestHeaders.TryAddWithoutValidation("authorization", authorization); client.DefaultRequestHeaders.Add("timestamps", timeStamp); } var httpData = new StringContent(bodyJson, Encoding.UTF8, mediaType); _logger.LogInformation($"POST 请求Url:{url}, Body:{bodyJson}"); var httpResponse = await client.PostAsync($"{url}", httpData); var stream = await httpResponse.Content.ReadAsStringAsync(); _logger.LogInformation($"请求结果:{stream}"); var response = JsonSerializer.Deserialize(stream, options); return response; } catch (Exception ex) { _logger.LogError(ex, "POST 方法请求错误!"); throw; } } /// /// Post /// /// /// /// /// /// /// /// public async Task PostAsync(string url, object? data = null, string? appId = "", string? appSecret = "", string? mediaType = "application/json") { try { var client = _httpClientFactory.CreateClient(); //var options = new JsonSerializerOptions //{ // DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, // PropertyNameCaseInsensitive = true //}; //_logger.LogInformation("卧槽,进来了。"); var bodyJson = data != null ? Newtonsoft.Json.JsonConvert.SerializeObject(data) : ""; if (!string.IsNullOrEmpty(appId)) { client.DefaultRequestHeaders.Add("appid", appId); } if (!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appSecret)) { var timeStamp = GetTimeStamp(); var sign = CreateSign(appId, bodyJson, appSecret, timeStamp); var authorization = $"{appId}:{sign}"; client.DefaultRequestHeaders.TryAddWithoutValidation("authorization", authorization); client.DefaultRequestHeaders.Add("timestamps", timeStamp); } var httpData = new StringContent(bodyJson, Encoding.UTF8, mediaType); _logger.LogInformation($"POST 请求Url:{url}, Body:{bodyJson}"); var httpResponse = await client.PostAsync($"{url}", httpData); var stream = await httpResponse.Content.ReadAsStringAsync(); _logger.LogInformation($"请求结果:{stream}"); var response = Newtonsoft.Json.JsonConvert.DeserializeObject(stream); return response; } catch (Exception ex) { _logger.LogError(ex, "POST 方法请求错误!"); throw; } } public async Task PostAsync(string url, object? data = null, string? appId = "", string? appSecret = "", string? mediaType = "application/json") { try { var client = _httpClientFactory.CreateClient(); var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true }; var bodyJson = data != null ? JsonSerializer.Serialize(data, options) : ""; if (!string.IsNullOrEmpty(appId)) { client.DefaultRequestHeaders.Add("appid", appId); } if (!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appSecret)) { var timeStamp = GetTimeStamp(); var sign = CreateSign(appId, bodyJson, appSecret, timeStamp); var authorization = $"{appId}:{sign}"; client.DefaultRequestHeaders.TryAddWithoutValidation("authorization", authorization); client.DefaultRequestHeaders.Add("timestamps", timeStamp); } var httpData = new StringContent(bodyJson, Encoding.UTF8, mediaType); Log($"POST 请求Url:{url}, Body:{bodyJson}"); var httpResponse = await client.PostAsync($"{url}", httpData); var response = await httpResponse.Content.ReadAsStringAsync(); Log($"请求结果:{response}"); return response; } catch (Exception ex) { _logger.LogError(ex, "POST 方法请求错误!"); throw; } } /// /// Get /// /// /// /// /// /// public async Task GetAsync(string url, string appId = "", string appSecret = "", int timeout = 10000) { try { var client = _httpClientFactory.CreateClient(); client.Timeout = TimeSpan.FromMilliseconds(timeout); var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true }; if (!string.IsNullOrEmpty(appId)) { client.DefaultRequestHeaders.Add("appid", appId); } if (!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appSecret)) { var uri = new Uri(url); var query = uri.Query; var param = new Dictionary(); if (query != null) { foreach (var item in query.Split('&')) { var sp = item.Split("="); if (sp.Count() > 1) { param.Add(sp[0].Replace("?", ""), sp[1]); } } } var timeStamp = GetTimeStamp(); param = param.OrderBy(m => m.Key).ToDictionary(m => m.Key, n => n.Value); var paramStr = JsonSerializer.Serialize(param, options); var sign = CreateSign(appId, paramStr, appSecret, timeStamp); var authorization = $"{appId}:{sign}"; client.DefaultRequestHeaders.TryAddWithoutValidation("authorization", authorization); client.DefaultRequestHeaders.Add("timestamps", timeStamp); } Log($"GET 请求Url:{url}"); var httpResponse = await client.GetAsync($"{url}"); var stream = await httpResponse.Content.ReadAsStringAsync(); Log($"请求结果:{stream}"); var response = JsonSerializer.Deserialize(stream, options); return response; } catch (Exception ex) { _logger.LogError(ex, "GET 方法请求错误!"); throw; } } /// /// Get /// /// /// /// /// /// /// public async Task GetAsync(string url, Dictionary param, string appId = "", string appSecret = "") { try { var client = _httpClientFactory.CreateClient(); client.Timeout = TimeSpan.FromSeconds(30); var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true }; var urlParam = string.Join("&", param.Select(m => m.Key + "=" + m.Value)); if (url.IndexOf('?') > -1) { url += urlParam; } else { url = url + "?" + urlParam; } if (!string.IsNullOrEmpty(appId)) { client.DefaultRequestHeaders.Add("appid", appId); } if (!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appSecret)) { var timeStamp = GetTimeStamp(); param = param.OrderBy(m => m.Key).ToDictionary(m => m.Key, n => n.Value); var paramStr = JsonSerializer.Serialize(param, options); var sign = CreateSign(appId, paramStr, appSecret, timeStamp); var authorization = $"{appId}:{sign}"; client.DefaultRequestHeaders.TryAddWithoutValidation("authorization", authorization); client.DefaultRequestHeaders.Add("timestamps", timeStamp); } Log($"GET 请求Url:{url}"); var httpResponse = await client.GetAsync($"{url}"); var stream = await httpResponse.Content.ReadAsStringAsync(); Log($"请求结果:{stream}"); var response = JsonSerializer.Deserialize(stream, options); return response; } catch (Exception ex) { _logger.LogError(ex, "GET 方法请求错误!"); throw; } } /// /// Get /// /// /// /// /// /// public async Task GetAsync(string url, string appId = "", string appSecret = "") { try { var client = _httpClientFactory.CreateClient(); client.Timeout = TimeSpan.FromSeconds(30); var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true }; if (!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appSecret)) { var uri = new Uri(url); var query = uri.Query; var param = new Dictionary(); if (query != null) { foreach (var item in query.Split('&')) { var sp = item.Split("="); if (sp.Count() > 1) { param.Add(sp[0].Replace("?", ""), sp[1]); } } } var timeStamp = GetTimeStamp(); param = param.OrderBy(m => m.Key).ToDictionary(m => m.Key, n => n.Value); var paramStr = JsonSerializer.Serialize(param, options); var sign = CreateSign(appId, paramStr, appSecret, timeStamp); var authorization = $"{appId}:{sign}"; client.DefaultRequestHeaders.TryAddWithoutValidation("authorization", authorization); client.DefaultRequestHeaders.Add("timestamps", timeStamp); } Log($"GET 请求Url:{url}"); var httpResponse = await client.GetAsync($"{url}"); var response = await httpResponse.Content.ReadAsStringAsync(); Log($"请求结果:{response}"); return response; } catch (Exception ex) { _logger.LogError(ex, "GET 方法请求错误!"); throw; } } /// /// Get /// /// /// /// /// /// /// public async Task GetAsync(string url, Dictionary param, string appId = "", string appSecret = "") { try { var client = _httpClientFactory.CreateClient(); client.Timeout = TimeSpan.FromSeconds(30); var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true }; var urlParam = string.Join("&", param.Select(m => m.Key + "=" + m.Value)); if (url.IndexOf('?') > -1) { url += urlParam; } else { url = url + "?" + urlParam; } if (!string.IsNullOrEmpty(appId)) { client.DefaultRequestHeaders.Add("appid", appId); } if (!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appSecret)) { var timeStamp = GetTimeStamp(); param = param.OrderBy(m => m.Key).ToDictionary(m => m.Key, n => n.Value); var paramStr = JsonSerializer.Serialize(param, options); var sign = CreateSign(appId, paramStr, appSecret, timeStamp); var authorization = $"{appId}:{sign}"; client.DefaultRequestHeaders.TryAddWithoutValidation("authorization", authorization); client.DefaultRequestHeaders.Add("timestamps", timeStamp); } Log($"GET 请求Url:{url}"); var httpResponse = await client.GetAsync($"{url}"); var response = await httpResponse.Content.ReadAsStringAsync(); Log($"请求结果:{response}"); return response; } catch (Exception ex) { _logger.LogError(ex, "GET 方法请求错误!"); throw; } } /// /// 生成签名 /// /// /// /// /// /// private static string CreateSign(string appId, string bodyJson, string secret, string timestamps) { var enStrList = new string[] { appId, bodyJson, secret, timestamps }; Array.Sort(enStrList, string.CompareOrdinal); var enStr = string.Join("", enStrList); var md = GetMd5Hash(enStr); return md; } /// /// 计算 md5 /// /// /// private static string GetMd5Hash(string enCode) { string res = ""; byte[] data = Encoding.GetEncoding("utf-8").GetBytes(enCode); MD5 md5 = MD5.Create(); byte[] bytes = md5.ComputeHash(data); for (int i = 0; i < bytes.Length; i++) { res += bytes[i].ToString("x2"); } return res; } /// /// 获取时间戳 /// /// public static string GetTimeStamp() { TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } /// /// 加密 /// /// /// /// private static string EncyptData(string ciphertext, string accessKey) { SymmetricAlgorithm des = DES.Create(); Encoding utf = new UTF8Encoding(); byte[] key = utf.GetBytes(accessKey); byte[] iv = { 0x75, 0x70, 0x63, 0x68, 0x69, 0x6e, 0x61, 0x31 }; ICryptoTransform encryptor = des.CreateEncryptor(key, iv); byte[] data = utf.GetBytes(ciphertext); byte[] encData = encryptor.TransformFinalBlock(data, 0, data.Length); return Convert.ToBase64String(encData); } /// /// 解密 /// /// /// /// private static string DecyptData(string cryptograph, string accessKey) { SymmetricAlgorithm des = DES.Create(); Encoding utf = new UTF8Encoding(); byte[] key = utf.GetBytes(accessKey); byte[] iv = { 0x75, 0x70, 0x63, 0x68, 0x69, 0x6e, 0x61, 0x31 }; ICryptoTransform decryptor = des.CreateDecryptor(key, iv); byte[] encData = Convert.FromBase64String(cryptograph); byte[] data = decryptor.TransformFinalBlock(encData, 0, encData.Length); return utf.GetString(data); } /// /// AES加密算法 /// /// 明文字符串 /// 字符串 private static string EncryptByAES(string input, string key, string iv) { if (string.IsNullOrWhiteSpace(input)) { return input; } Aes aes = Aes.Create(); aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; aes.FeedbackSize = 128; aes.Key = Encoding.UTF8.GetBytes(key); aes.IV = Encoding.UTF8.GetBytes(iv); ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV); using MemoryStream msEncrypt = new(); using CryptoStream csEncrypt = new(msEncrypt, encryptor, CryptoStreamMode.Write); using (StreamWriter swEncrypt = new(csEncrypt)) { swEncrypt.Write(input); } byte[] bytes = msEncrypt.ToArray(); return Convert.ToBase64String(bytes); } #endregion 正常请求 } }