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和策略模式。
相关推荐
多加点辣也没关系12 小时前
JavaScript|第4章:类型转换
开发语言·javascript
聪慧的水蜜桃12 小时前
【YFIOs】用C#开发硬件之设备上云
开发语言·c#
yqcoder13 小时前
httpOnly 是什么,又有什么用?
开发语言·前端·javascript
驭渊的小故事13 小时前
网络原理01(两千字解析)
网络
wuqingshun31415914 小时前
重写equals而不重写hashCode,会出什么问题?
java·开发语言
飞猪~14 小时前
LangChain python 版本 第一集
开发语言·python·langchain
KaMeidebaby15 小时前
卡梅德生物技术快报|小 RNA 适配体合成 + 多方法亲和力表征全流程标准化操作手册
前端·网络·数据库·人工智能·算法
李燚15 小时前
Go 项目怎么组织:DDD 4 层 vs MVC vs 脚本式
开发语言·golang·mvc·ddd·agent框架·eino
2zcode16 小时前
免费开源项目文档:基于MATLAB图像处理的啤酒瓶口缺陷检测系统设计与实现
开发语言·图像处理·matlab
人工智能时代 准备好了吗16 小时前
AI回答内容进入率监测:引用识别、文本匹配与语义判断
开发语言·人工智能·python