using System; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using System.Collections.Generic; namespace LTEMvcApp.Services { /// /// HTTP客户端服务 - 提供HTTP请求功能 /// public class HttpClientService { private readonly HttpClient _httpClient; private readonly ILogger _logger; public HttpClientService(HttpClient httpClient, ILogger logger) { _httpClient = httpClient; _logger = logger; // 设置默认请求头 _httpClient.DefaultRequestHeaders.Add("User-Agent", "LTEMvcApp/1.0"); _httpClient.Timeout = TimeSpan.FromSeconds(120); _logger.LogInformation("HttpClientService 初始化完成"); } #region GET请求方法 /// /// 发送GET请求 /// /// 请求URL /// 自定义请求头 /// 响应内容 public async Task GetAsync(string url, Dictionary? headers = null) { try { _logger.LogInformation("发送GET请求到: {Url}", url); using var request = new HttpRequestMessage(HttpMethod.Get, url); if (headers != null) { foreach (var header in headers) { request.Headers.Add(header.Key, header.Value); } } var response = await _httpClient.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); _logger.LogInformation("GET请求成功,响应长度: {Length}", content.Length); return content; } catch (Exception ex) { _logger.LogError(ex, "GET请求失败: {Url}", url); throw; } } /// /// 发送GET请求并反序列化为指定类型 /// /// 目标类型 /// 请求URL /// 自定义请求头 /// 反序列化的对象 public async Task GetAsync(string url, Dictionary? headers = null) { var json = await GetAsync(url, headers); return JsonConvert.DeserializeObject(json) ?? throw new InvalidOperationException("反序列化失败"); } #endregion #region POST请求方法 /// /// 发送POST请求 /// /// 请求URL /// 请求内容 /// 内容类型 /// 自定义请求头 /// 响应内容 public async Task PostAsync(string url, string content, string contentType = "application/json", Dictionary? headers = null) { try { _logger.LogInformation("发送POST请求到: {Url}", url); using var request = new HttpRequestMessage(HttpMethod.Post, url); if (headers != null) { foreach (var header in headers) { request.Headers.Add(header.Key, header.Value); } } request.Content = new StringContent(content, Encoding.UTF8, contentType); var response = await _httpClient.SendAsync(request); response.EnsureSuccessStatusCode(); var responseContent = await response.Content.ReadAsStringAsync(); _logger.LogInformation("POST请求成功,响应长度: {Length}", responseContent.Length); return responseContent; } catch (Exception ex) { _logger.LogError(ex, "POST请求失败: {Url}", url); throw; } } /// /// 发送POST请求(JSON格式) /// /// 请求URL /// 要发送的数据对象 /// 自定义请求头 /// 响应内容 public async Task PostJsonAsync(string url, object data, Dictionary? headers = null) { var json = JsonConvert.SerializeObject(data); return await PostAsync(url, json, "application/json", headers); } /// /// 发送POST请求并反序列化响应 /// /// 响应类型 /// 请求URL /// 要发送的数据对象 /// 自定义请求头 /// 反序列化的响应对象 public async Task PostJsonAsync(string url, object data, Dictionary? headers = null) { var json = await PostJsonAsync(url, data, headers); return JsonConvert.DeserializeObject(json) ?? throw new InvalidOperationException("反序列化失败"); } #endregion #region PUT请求方法 /// /// 发送PUT请求 /// /// 请求URL /// 请求内容 /// 内容类型 /// 自定义请求头 /// 响应内容 public async Task PutAsync(string url, string content, string contentType = "application/json", Dictionary? headers = null) { try { _logger.LogInformation("发送PUT请求到: {Url}", url); using var request = new HttpRequestMessage(HttpMethod.Put, url); if (headers != null) { foreach (var header in headers) { request.Headers.Add(header.Key, header.Value); } } request.Content = new StringContent(content, Encoding.UTF8, contentType); var response = await _httpClient.SendAsync(request); response.EnsureSuccessStatusCode(); var responseContent = await response.Content.ReadAsStringAsync(); _logger.LogInformation("PUT请求成功,响应长度: {Length}", responseContent.Length); return responseContent; } catch (HttpRequestException ex) { _logger.LogError(ex, "PUT请求失败: {Url}", url); throw; } catch (TaskCanceledException ex) { _logger.LogError(ex, "PUT请求超时: {Url}", url); throw; } } /// /// 发送PUT请求(JSON格式) /// /// 请求URL /// 要发送的数据对象 /// 自定义请求头 /// 响应内容 public async Task PutJsonAsync(string url, object data, Dictionary? headers = null) { var json = JsonConvert.SerializeObject(data); return await PutAsync(url, json, "application/json", headers); } #endregion #region DELETE请求方法 /// /// 发送DELETE请求 /// /// 请求URL /// 自定义请求头 /// 响应内容 public async Task DeleteAsync(string url, Dictionary? headers = null) { try { _logger.LogInformation("发送DELETE请求到: {Url}", url); using var request = new HttpRequestMessage(HttpMethod.Delete, url); if (headers != null) { foreach (var header in headers) { request.Headers.Add(header.Key, header.Value); } } var response = await _httpClient.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); _logger.LogInformation("DELETE请求成功,响应长度: {Length}", content.Length); return content; } catch (HttpRequestException ex) { _logger.LogError(ex, "DELETE请求失败: {Url}", url); throw; } catch (TaskCanceledException ex) { _logger.LogError(ex, "DELETE请求超时: {Url}", url); throw; } } #endregion #region 工具方法 /// /// 设置默认请求头 /// /// 头部名称 /// 头部值 public void SetDefaultHeader(string name, string value) { _httpClient.DefaultRequestHeaders.Remove(name); _httpClient.DefaultRequestHeaders.Add(name, value); _logger.LogInformation("设置默认请求头: {Name} = {Value}", name, value); } /// /// 设置超时时间 /// /// 超时时间 public void SetTimeout(TimeSpan timeout) { _httpClient.Timeout = timeout; _logger.LogInformation("设置超时时间: {Timeout}", timeout); } /// /// 获取当前HttpClient实例 /// /// HttpClient实例 public HttpClient GetHttpClient() { return _httpClient; } #endregion } }