C# 网络编程-关于HttpClient使用方式(三)

前面有讲到比较底层一点的请求方式C# 网络编程-关于HttpWebRequest使用方式(二):,官方是推荐使用HttpClient的常用请求方式,可能为了在跨平台兼容吧,HttpClient涵盖GET、POST、PUT、DELETE等方法


一、基础请求方式

1. GET 请求(获取数据)
csharp 复制代码
using System.Net.Http;
using System.Threading.Tasks;

public async Task<string> GetAsStringAsync(string url)
{
    using (HttpClient client = new HttpClient())
    {
        try
        {
            HttpResponseMessage response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode(); // 检查HTTP状态码(如200)
            return await response.Content.ReadAsStringAsync();
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"请求失败: {ex.Message}");
            return null;
        }
    }
}
2. POST 请求(提交数据)
csharp 复制代码
public async Task<string> PostAsStringAsync(string url, string jsonContent)
{
    using (HttpClient client = new HttpClient())
    {
        try
        {
            // 创建JSON内容
            StringContent content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
            HttpResponseMessage response = await client.PostAsync(url, content);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"请求失败: {ex.Message}");
            return null;
        }
    }
}
3. PUT 请求(更新数据)
csharp 复制代码
public async Task<string> PutAsStringAsync(string url, string jsonContent)
{
    using (HttpClient client = new HttpClient())
    {
        try
        {
            StringContent content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
            HttpResponseMessage response = await client.PutAsync(url, content);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"请求失败: {ex.Message}");
            return null;
        }
    }
}
4. DELETE 请求(删除数据)
csharp 复制代码
public async Task<string> DeleteAsStringAsync(string url)
{
    using (HttpClient client = new HttpClient())
    {
        try
        {
            HttpResponseMessage response = await client.DeleteAsync(url);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"请求失败: {ex.Message}");
            return null;
        }
    }
}

二、配置与最佳实践

1. 配置超时时间
csharp 复制代码
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(10); // 设置超时时间为10秒
2. 添加请求头(如Authorization、Content-Type)
csharp 复制代码
client.DefaultRequestHeaders.Add("Authorization", "Bearer your_token");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
3. 避免重复创建HttpClient实例
  • 问题 :频繁创建HttpClient可能导致Socket资源耗尽。

  • 解决方案 :在应用程序生命周期中重用单个HttpClient实例:

    csharp 复制代码
    // 使用单例模式
    private static readonly HttpClient _client = new HttpClient();
4. 使用HttpClientFactory(推荐在ASP.NET Core中使用)
csharp 复制代码
// 在Startup.cs中配置:
services.AddHttpClient<IMyService, MyService>()
    .SetBaseAddress(new Uri("https://api.example.com"))
    .AddPolicyHandler(HttpPolicyRegistry); // 添加重试、超时等策略

// 在服务中注入:
public class MyService : IMyService
{
    private readonly HttpClient _client;
    public MyService(HttpClient client) => _client = client;
}

三、处理响应与异常

1. 处理响应内容
  • 字符串响应

    csharp 复制代码
    string result = await response.Content.ReadAsStringAsync();
  • JSON反序列化

    csharp 复制代码
    var myObject = await response.Content.ReadFromJsonAsync<MyModel>();
    // 或使用Newtonsoft.Json:
    var myObject = JsonConvert.DeserializeObject<MyModel>(result);
2. 异常处理
csharp 复制代码
try
{
    // 发送请求
}
catch (HttpRequestException ex) when (ex.Message.Contains("404"))
{
    Console.WriteLine("资源未找到");
}
catch (TaskCanceledException ex)
{
    Console.WriteLine("请求超时");
}
catch (Exception ex)
{
    Console.WriteLine($"未知错误: {ex.Message}");
}

四、高级用法

1. 上传文件
csharp 复制代码
public async Task UploadFileAsync(string url, string filePath)
{
    using (HttpClient client = new HttpClient())
    {
        var content = new MultipartFormDataContent();
        var fileContent = new ByteArrayContent(File.ReadAllBytes(filePath));
        fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
        {
            Name = "file",
            FileName = Path.GetFileName(filePath)
        };
        content.Add(fileContent);
        
        await client.PostAsync(url, content);
    }
}
2. 发送表单数据(application/x-www-form-urlencoded)
csharp 复制代码
public async Task PostFormAsync(string url, Dictionary<string, string> formData)
{
    var content = new FormUrlEncodedContent(formData);
    await client.PostAsync(url, content);
}
3. 使用JSON序列化(System.Text.Json)
csharp 复制代码
var myObject = new MyModel { Name = "Test" };
var jsonContent = JsonSerializer.Serialize(myObject);
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

五、完整示例

csharp 复制代码
public class ApiService
{
    private readonly HttpClient _client;

    public ApiService(HttpClient client)
    {
        _client = client;
    }

    public async Task<T> GetAsync<T>(string endpoint)
    {
        var response = await _client.GetAsync(endpoint);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<T>();
    }

    public async Task<T> PostAsync<T>(string endpoint, object data)
    {
        var content = new StringContent(JsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
        var response = await _client.PostAsync(endpoint, content);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<T>();
    }
}

关键注意事项

  1. 异步编程 :始终使用async/await,避免阻塞。
  2. 资源管理 :重用HttpClient实例,避免创建过多实例。
  3. 异常处理 :捕获HttpRequestExceptionTaskCanceledException
  4. 安全性 :对于敏感操作(如身份验证),使用HttpClientFactory和策略模式。
相关推荐
m0_748240254 小时前
Windows编程+使用C++编写EXE加壳程序
开发语言·c++·windows
兮兮能吃能睡5 小时前
R语言模型分析(一)(1)
开发语言·r语言
wuk9987 小时前
基于有限差分法的二维平面热传导模型MATLAB实现
开发语言·matlab·平面
Black蜡笔小新7 小时前
赋能智慧货运:视频汇聚平台EasyCVR打造货运汽车安全互联网视频监控与管理方案
网络·汽车·音视频
初见无风9 小时前
2.5 Lua代码中string类型常用API
开发语言·lua·lua5.4
做运维的阿瑞9 小时前
用 Python 构建稳健的数据分析流水线
开发语言·python·数据分析
左师佑图9 小时前
综合案例:Python 数据处理——从Excel文件到数据分析
开发语言·python·数据分析·excel·pandas
陌路209 小时前
C23构造函数与析构函数
开发语言·c++
鹿鸣天涯10 小时前
关于进一步做好网络安全等级保护有关工作的问题释疑-【二级以上系统重新备案】、【备案证明有效期三年】
网络·安全·web安全
周杰伦_Jay10 小时前
【网络核心协议全景解析】IP、TCP、UDP与HTTP(多表格深度对比)
网络·tcp/ip·udp