C# HttpHelper 类

using System;
using System.Net.Http;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;

public class VipSoftHttpHelper
{
    private readonly HttpClient _httpClient;

    private VipSoftHttpHelper() {
        _httpClient = new HttpClient(new HttpClientHandler()
        {
            UseProxy = false,
            // 其他配置...
        });
        _httpClient.DefaultRequestHeaders.Add("User-Agent", "C#-Client");
    }
     
    private static readonly Lazy<VipSoftHttpHelper> instance = new Lazy<VipSoftHttpHelper>(() => new VipSoftHttpHelper());


    public static VipSoftHttpHelper Instance => instance.Value;


    /// <summary>
    /// POST 请求 Java API 接口
    /// </summary>
    /// <param name="url">请求地址</param>
    /// <param name="postData">请求数据对象</param>
    /// <param name="timeoutSeconds">超时时间(秒)</param>
    /// <param name="headers">请求头</param>
    /// <returns>响应字符串</returns>
    public string HttpPost(string url, object postData, int timeoutSeconds = 30, Dictionary<string, object> headers = null)
    {
        try
        {
            // 序列化数据
            string jsonContent = Newtonsoft.Json.JsonConvert.SerializeObject(postData);
            LogHelper.Debug($"HTTP POST: {url}, Timeout: {timeoutSeconds}s, Data: {jsonContent}");
            // 使用 HttpRequestMessage 而不是直接修改 HttpClient
            var request = new HttpRequestMessage(HttpMethod.Post, url)
            {
                Content = new StringContent(jsonContent, Encoding.UTF8, "application/json")
            };

            // 添加自定义请求头到本次请求
            if (headers != null)
            {
                foreach (var header in headers)
                {
                    if (header.Key.ToLower() == "content-type")
                        continue;

                    request.Headers.TryAddWithoutValidation(header.Key, header.Value);
                }
            }

            // 使用 CancellationToken 实现超时
            CancellationTokenSource cts = new CancellationTokenSource();
            try
            {
                if (timeoutSeconds > 0)
                { 
                    cts.CancelAfter(TimeSpan.FromSeconds(timeoutSeconds)); // 兼容旧版本
                }

                // 发送请求
                HttpResponseMessage response = _httpClient.SendAsync(request, cts.Token).Result;

                // 确保请求成功
                response.EnsureSuccessStatusCode();

                // 读取响应内容
                return response.Content.ReadAsStringAsync().Result;
            }
            finally
            {
                cts?.Dispose();
            }
        }
        catch (AggregateException ae)
        {
            throw ae.InnerException ?? ae;
        }
        catch (TaskCanceledException) when (timeoutSeconds > 0)
        {
            throw new TimeoutException($"请求超时 ({timeoutSeconds}秒)");
        }
    }

    /// <summary>
    /// 带泛型返回值的 POST 请求
    /// </summary>
    public T HttpPost<T>(string url, object postData, int timeoutSeconds = 30, Dictionary<string, object> headers = null)
    {
        string responseJson = HttpPost(url, postData, timeoutSeconds, headers);
        return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseJson);
    }

    /// <summary>
    /// GET 请求
    /// </summary>
    public string HttpGet(string url, int timeoutSeconds = 30, Dictionary<string, object> headers = null)
    {
        try
        {
            // 使用 HttpRequestMessage 而不是直接修改 HttpClient 
            var request = new HttpRequestMessage(HttpMethod.Get, url); 
            // 添加自定义请求头到本次请求
            if (headers != null)
            {
                foreach (var header in headers)
                {
                    if (header.Key.ToLower() == "content-type")
                        continue;

                    request.Headers.TryAddWithoutValidation(header.Key, header.Value);
                }
            }


            // 使用 CancellationToken 实现超时
            CancellationTokenSource cts = new CancellationTokenSource();
            try
            {
                if (timeoutSeconds > 0)
                {
                    cts.CancelAfter(TimeSpan.FromSeconds(timeoutSeconds)); // 兼容旧版本
                }

                // 发送请求
                HttpResponseMessage response = _httpClient.SendAsync(request, cts.Token).Result;

                // 确保请求成功
                response.EnsureSuccessStatusCode();

                // 读取响应内容
                return response.Content.ReadAsStringAsync().Result;
            }
            finally
            {
                cts?.Dispose();
            }

        }
        catch (AggregateException ae)
        {
            throw ae.InnerException ?? ae;
        }
        catch (TaskCanceledException) when (timeoutSeconds > 0)
        {
            throw new TimeoutException($"请求超时 ({timeoutSeconds}秒)");
        }
    }

    /// <summary>
    /// 带泛型返回值的 GET 请求
    /// </summary>
    public T HttpGet<T>(string url, int timeoutSeconds = 30, Dictionary<string, object> headers = null)
    {
        string responseJson = HttpGet(url, timeoutSeconds, headers);
        return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseJson);
    }
}

✅ 代码优点
线程安全:使用 HttpRequestMessage 避免共享状态问题
兼容性好:使用 CancelAfter 兼容旧版 .NET Framework
资源管理:正确使用 try-finally 释放 CancellationTokenSource
异常处理:区分超时异常和其他异常
单例模式:正确复用 HttpClient 实例

posted @ 2025-11-18 08:01  VipSoft  阅读(3)  评论(0)    收藏  举报