lai_transfer/src/Tool/HttpTool/HttpService.cs

302 lines
9.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.Extensions.Logging;
using System.Text;
using System.Text.Json;
namespace lai_transfer.Tool.HttpTool;
public class HttpRequestConfig
{
public string? BaseUrl { get; set; }
public Dictionary<string, string> Headers { get; set; } = new();
public Dictionary<string, string> QueryParams { get; set; } = new();
public string? BearerToken { get; set; }
public TimeSpan? Timeout { get; set; }
public string? MediaType { get; set; } = "application/json";
public CancellationToken CancellationToken { get; set; } = CancellationToken.None;
}
public class HttpRequestConfig<T> : HttpRequestConfig
{
public T? Data { get; set; }
}
public interface IHttpService
{
Task<T?> GetAsync<T>(string url, HttpRequestConfig? config = null);
Task<string> GetStringAsync(string url, HttpRequestConfig? config = null);
Task<T?> PostAsync<T>(string url, object data, HttpRequestConfig? config = null);
Task<T?> PostAsync<T>(string url, HttpRequestConfig<T> config);
Task<T?> PutAsync<T>(string url, object data, HttpRequestConfig? config = null);
Task<bool> DeleteAsync(string url, HttpRequestConfig? config = null);
Task<Stream> GetStreamAsync(string url, HttpRequestConfig? config = null);
Task<byte[]> DownloadFileAsync(string url, HttpRequestConfig? config = null);
}
public class HttpService : IHttpService
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<HttpService> _logger;
public HttpService(IHttpClientFactory httpClientFactory, ILogger<HttpService> logger)
{
_httpClientFactory = httpClientFactory;
_logger = logger;
}
/// <summary>
/// ÅäÖÃHttpRequestMessage
/// </summary>
private HttpRequestMessage CreateHttpRequest(HttpMethod method, string url, HttpRequestConfig? config)
{
var requestUrl = BuildUrl(url, config);
var request = new HttpRequestMessage(method, requestUrl);
// ÉèÖÃÇëÇóÍ·
SetRequestHeaders(request, config);
return request;
}
/// <summary>
/// ¹¹½¨ÍêÕûURL£¨°üº¬²éѯ²ÎÊý£©
/// </summary>
private string BuildUrl(string url, HttpRequestConfig? config)
{
if (config?.QueryParams == null || !config.QueryParams.Any())
return url;
var uriBuilder = new UriBuilder(url);
var query = System.Web.HttpUtility.ParseQueryString(uriBuilder.Query);
foreach (var param in config.QueryParams)
{
query[param.Key] = param.Value;
}
uriBuilder.Query = query.ToString();
return uriBuilder.ToString();
}
/// <summary>
/// ÉèÖÃÇëÇóÍ·
/// </summary>
private void SetRequestHeaders(HttpRequestMessage request, HttpRequestConfig? config)
{
if (config == null) return;
// ÉèÖÃBearer Token
if (!string.IsNullOrEmpty(config.BearerToken))
{
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", config.BearerToken);
}
// ÉèÖÃ×Ô¶¨ÒåÇëÇóÍ·
foreach (var header in config.Headers)
{
request.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
// ÉèÖÃContent-Type
if (request.Content != null && !string.IsNullOrEmpty(config.MediaType))
{
request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(config.MediaType);
}
}
/// <summary>
/// ·¢ËÍHTTPÇëÇó
/// </summary>
private async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, HttpRequestConfig? config, string clientName = "DefaultClient")
{
using var httpClient = _httpClientFactory.CreateClient(clientName);
// ÉèÖó¬Ê±
if (config?.Timeout.HasValue == true)
{
httpClient.Timeout = config.Timeout.Value;
}
return await httpClient.SendAsync(request, config?.CancellationToken ?? CancellationToken.None);
}
/// <summary>
/// GETÇëÇó - ·µ»Ø·ºÐÍÀàÐÍ
/// </summary>
public async Task<T?> GetAsync<T>(string url, HttpRequestConfig? config = null)
{
try
{
var request = CreateHttpRequest(HttpMethod.Get, url, config);
var response = await SendAsync(request, config);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<T>(content, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
}
catch (Exception ex)
{
_logger.LogError(ex, "GETÇëÇóʧ°Ü: {Url}", url);
throw;
}
}
/// <summary>
/// GETÇëÇó - ·µ»Ø×Ö·û´®
/// </summary>
public async Task<string> GetStringAsync(string url, HttpRequestConfig? config = null)
{
try
{
var request = CreateHttpRequest(HttpMethod.Get, url, config);
var response = await SendAsync(request, config);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "GET×Ö·û´®ÇëÇóʧ°Ü: {Url}", url);
throw;
}
}
/// <summary>
/// POSTÇëÇó
/// </summary>
public async Task<T?> PostAsync<T>(string url, object data, HttpRequestConfig? config = null)
{
try
{
var request = CreateHttpRequest(HttpMethod.Post, url, config);
// ÅжÏdataÊDz»ÊÇstring ²»Êǵϰ²ÅÐòÁл°
string json;
if (data is string str)
{
// Èç¹û data ÒѾ­ÊÇ×Ö·û´®£¬Ö±½ÓʹÓÃ
json = str;
}
else
{
// Èç¹ûÊǶÔÏó£¬ÐòÁл¯Îª JSON
json = JsonSerializer.Serialize(data);
}
request.Content = new StringContent(json, Encoding.UTF8, config?.MediaType ?? "application/json");
var response = await SendAsync(request, config);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<T>(content, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
}
catch (Exception ex)
{
_logger.LogError(ex, "POSTÇëÇóʧ°Ü: {Url}", url);
throw;
}
}
/// <summary>
/// POSTÇëÇó - ·ºÐÍÅäÖð汾
/// </summary>
public async Task<T?> PostAsync<T>(string url, HttpRequestConfig<T> config)
{
return await PostAsync<T>(url, config.Data!, config);
}
/// <summary>
/// PUTÇëÇó
/// </summary>
public async Task<T?> PutAsync<T>(string url, object data, HttpRequestConfig? config = null)
{
try
{
var request = CreateHttpRequest(HttpMethod.Put, url, config);
var json = JsonSerializer.Serialize(data);
request.Content = new StringContent(json, Encoding.UTF8, config?.MediaType ?? "application/json");
var response = await SendAsync(request, config);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<T>(content, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
}
catch (Exception ex)
{
_logger.LogError(ex, "PUTÇëÇóʧ°Ü: {Url}", url);
throw;
}
}
/// <summary>
/// DELETEÇëÇó
/// </summary>
public async Task<bool> DeleteAsync(string url, HttpRequestConfig? config = null)
{
try
{
var request = CreateHttpRequest(HttpMethod.Delete, url, config);
var response = await SendAsync(request, config);
return response.IsSuccessStatusCode;
}
catch (Exception ex)
{
_logger.LogError(ex, "DELETEÇëÇóʧ°Ü: {Url}", url);
throw;
}
}
/// <summary>
/// ÏÂÔØÎļþÁ÷
/// </summary>
public async Task<Stream> GetStreamAsync(string url, HttpRequestConfig? config = null)
{
try
{
var request = CreateHttpRequest(HttpMethod.Get, url, config);
var response = await SendAsync(request, config);
response.EnsureSuccessStatusCode();
var stream = await response.Content.ReadAsStreamAsync();
// ×ªÒÆËùÓÐȨ£¬µ÷Ó÷½¸ºÔðÊÍ·Å
response = null;
return stream;
}
catch (Exception ex)
{
_logger.LogError(ex, "»ñÈ¡Á÷ʧ°Ü: {Url}", url);
throw;
}
}
/// <summary>
/// ÏÂÔØÎļþ×Ö½ÚÊý×é
/// </summary>
public async Task<byte[]> DownloadFileAsync(string url, HttpRequestConfig? config = null)
{
try
{
using var stream = await GetStreamAsync(url, config);
using var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream);
return memoryStream.ToArray();
}
catch (Exception ex)
{
_logger.LogError(ex, "ÏÂÔØÎļþʧ°Ü: {Url}", url);
throw;
}
}
}