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.
 
 
 

301 lines
11 KiB

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
{
/// <summary>
/// HTTP客户端服务 - 提供HTTP请求功能
/// </summary>
public class HttpClientService
{
private readonly HttpClient _httpClient;
private readonly ILogger<HttpClientService> _logger;
public HttpClientService(HttpClient httpClient, ILogger<HttpClientService> logger)
{
_httpClient = httpClient;
_logger = logger;
// 设置默认请求头
_httpClient.DefaultRequestHeaders.Add("User-Agent", "LTEMvcApp/1.0");
_httpClient.Timeout = TimeSpan.FromSeconds(120);
_logger.LogInformation("HttpClientService 初始化完成");
}
#region GET请求方法
/// <summary>
/// 发送GET请求
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="headers">自定义请求头</param>
/// <returns>响应内容</returns>
public async Task<string> GetAsync(string url, Dictionary<string, string>? 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;
}
}
/// <summary>
/// 发送GET请求并反序列化为指定类型
/// </summary>
/// <typeparam name="T">目标类型</typeparam>
/// <param name="url">请求URL</param>
/// <param name="headers">自定义请求头</param>
/// <returns>反序列化的对象</returns>
public async Task<T> GetAsync<T>(string url, Dictionary<string, string>? headers = null)
{
var json = await GetAsync(url, headers);
return JsonConvert.DeserializeObject<T>(json) ?? throw new InvalidOperationException("反序列化失败");
}
#endregion
#region POST请求方法
/// <summary>
/// 发送POST请求
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="content">请求内容</param>
/// <param name="contentType">内容类型</param>
/// <param name="headers">自定义请求头</param>
/// <returns>响应内容</returns>
public async Task<string> PostAsync(string url, string content, string contentType = "application/json", Dictionary<string, string>? 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;
}
}
/// <summary>
/// 发送POST请求(JSON格式)
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="data">要发送的数据对象</param>
/// <param name="headers">自定义请求头</param>
/// <returns>响应内容</returns>
public async Task<string> PostJsonAsync(string url, object data, Dictionary<string, string>? headers = null)
{
var json = JsonConvert.SerializeObject(data);
return await PostAsync(url, json, "application/json", headers);
}
/// <summary>
/// 发送POST请求并反序列化响应
/// </summary>
/// <typeparam name="T">响应类型</typeparam>
/// <param name="url">请求URL</param>
/// <param name="data">要发送的数据对象</param>
/// <param name="headers">自定义请求头</param>
/// <returns>反序列化的响应对象</returns>
public async Task<T> PostJsonAsync<T>(string url, object data, Dictionary<string, string>? headers = null)
{
var json = await PostJsonAsync(url, data, headers);
return JsonConvert.DeserializeObject<T>(json) ?? throw new InvalidOperationException("反序列化失败");
}
#endregion
#region PUT请求方法
/// <summary>
/// 发送PUT请求
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="content">请求内容</param>
/// <param name="contentType">内容类型</param>
/// <param name="headers">自定义请求头</param>
/// <returns>响应内容</returns>
public async Task<string> PutAsync(string url, string content, string contentType = "application/json", Dictionary<string, string>? 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;
}
}
/// <summary>
/// 发送PUT请求(JSON格式)
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="data">要发送的数据对象</param>
/// <param name="headers">自定义请求头</param>
/// <returns>响应内容</returns>
public async Task<string> PutJsonAsync(string url, object data, Dictionary<string, string>? headers = null)
{
var json = JsonConvert.SerializeObject(data);
return await PutAsync(url, json, "application/json", headers);
}
#endregion
#region DELETE请求方法
/// <summary>
/// 发送DELETE请求
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="headers">自定义请求头</param>
/// <returns>响应内容</returns>
public async Task<string> DeleteAsync(string url, Dictionary<string, string>? 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 工具方法
/// <summary>
/// 设置默认请求头
/// </summary>
/// <param name="name">头部名称</param>
/// <param name="value">头部值</param>
public void SetDefaultHeader(string name, string value)
{
_httpClient.DefaultRequestHeaders.Remove(name);
_httpClient.DefaultRequestHeaders.Add(name, value);
_logger.LogInformation("设置默认请求头: {Name} = {Value}", name, value);
}
/// <summary>
/// 设置超时时间
/// </summary>
/// <param name="timeout">超时时间</param>
public void SetTimeout(TimeSpan timeout)
{
_httpClient.Timeout = timeout;
_logger.LogInformation("设置超时时间: {Timeout}", timeout);
}
/// <summary>
/// 获取当前HttpClient实例
/// </summary>
/// <returns>HttpClient实例</returns>
public HttpClient GetHttpClient()
{
return _httpClient;
}
#endregion
}
}