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

发布于:2025-06-22 ⋅ 阅读:(12) ⋅ 点赞:(0)

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


一、基础请求方式

1. GET 请求(获取数据)
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 请求(提交数据)
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 请求(更新数据)
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 请求(删除数据)
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. 配置超时时间
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(10); // 设置超时时间为10秒
2. 添加请求头(如Authorization、Content-Type)
client.DefaultRequestHeaders.Add("Authorization", "Bearer your_token");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
3. 避免重复创建HttpClient实例
  • 问题:频繁创建HttpClient可能导致Socket资源耗尽。
  • 解决方案:在应用程序生命周期中重用单个HttpClient实例:
    // 使用单例模式
    private static readonly HttpClient _client = new HttpClient();
    
4. 使用HttpClientFactory(推荐在ASP.NET Core中使用)
// 在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. 处理响应内容
  • 字符串响应
    string result = await response.Content.ReadAsStringAsync();
    
  • JSON反序列化
    var myObject = await response.Content.ReadFromJsonAsync<MyModel>();
    // 或使用Newtonsoft.Json:
    var myObject = JsonConvert.DeserializeObject<MyModel>(result);
    
2. 异常处理
try
{
    // 发送请求
}
catch (HttpRequestException ex) when (ex.Message.Contains("404"))
{
    Console.WriteLine("资源未找到");
}
catch (TaskCanceledException ex)
{
    Console.WriteLine("请求超时");
}
catch (Exception ex)
{
    Console.WriteLine($"未知错误: {ex.Message}");
}

四、高级用法

1. 上传文件
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)
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)
var myObject = new MyModel { Name = "Test" };
var jsonContent = JsonSerializer.Serialize(myObject);
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

五、完整示例

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和策略模式。

网站公告

今日签到

点亮在社区的每一天
去签到