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和策略模式。
相关推荐
teeeeeeemo10 分钟前
Number.toFixed() 与 Math.round() 深度对比解析
开发语言·前端·javascript·笔记
我在北京coding16 分钟前
Uncaught (in promise) TypeError: x.isoWeek is not a function
开发语言·javascript·vue.js
showmethetime18 分钟前
[设计模式]创建型模式-单例模式
开发语言
Y1_again_0_again31 分钟前
Java 包装类详解
java·开发语言
CC大煊1 小时前
【java】@RestController和@Controller的区别
java·开发语言
Ven%1 小时前
掌握Bash脚本编写:从服务启动脚本到语法精要
linux·服务器·开发语言·chrome·bash
gc_22991 小时前
C#测试调用ClosedXML根据批注设置excel单元格内容
c#·批注·closedxml
安全系统学习2 小时前
【网络安全】文件上传型XSS攻击解析
开发语言·python·算法·安全·web安全
谷雪_6582 小时前
学习华为 ensp 的学习心得体会
网络·学习·华为·网络工程·ensp