跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C Sharp HTTP 客户端
”︁(章节)
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= C# HTTP客户端 = HTTP客户端是C#网络编程中用于发送HTTP请求和接收HTTP响应的核心组件。.NET框架提供了多种方式来实现HTTP通信,包括传统的'''HttpWebRequest'''、'''WebClient''',以及现代推荐的'''HttpClient'''类。本章将重点介绍这些技术的使用方法、最佳实践和实际应用场景。 == 概述 == HTTP客户端允许应用程序与Web服务器进行通信,发送请求(如GET、POST等)并处理响应。在C#中,主要使用以下类: * '''HttpWebRequest''':早期的底层HTTP客户端实现 * '''WebClient''':更高级别的封装,简化常见操作 * '''HttpClient''':.NET 4.5+引入的现代HTTP客户端,支持异步操作 随着.NET的发展,'''HttpClient'''已成为推荐选择,因为它: * 支持异步编程模型 * 可重用连接(减少资源消耗) * 更灵活的请求/响应处理 * 更好的性能 == HttpClient 基础 == HttpClient位于'''System.Net.Http'''命名空间,是处理HTTP请求的主要类。 === 基本用法 === <syntaxhighlight lang="csharp"> using System; using System.Net.Http; using System.Threading.Tasks; class Program { static async Task Main(string[] args) { // 创建HttpClient实例 using HttpClient client = new HttpClient(); // 发送GET请求 HttpResponseMessage response = await client.GetAsync("https://api.example.com/data"); // 确保请求成功 response.EnsureSuccessStatusCode(); // 读取响应内容 string responseBody = await response.Content.ReadAsStringAsync(); Console.WriteLine(responseBody); } } </syntaxhighlight> '''输出示例''': <pre> { "userId": 1, "id": 1, "title": "示例数据", "completed": false } </pre> === 关键组件 === * '''HttpClient''':发送请求和接收响应的主类 * '''HttpRequestMessage''':表示HTTP请求消息 * '''HttpResponseMessage''':表示HTTP响应消息 * '''HttpContent''':表示HTTP内容(请求体或响应体) == 高级特性 == === 自定义请求头 === <syntaxhighlight lang="csharp"> using (HttpClient client = new HttpClient()) { // 添加自定义请求头 client.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0"); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // 添加授权头 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "your_token_here"); var response = await client.GetAsync("https://api.example.com/protected"); // 处理响应... } </syntaxhighlight> === POST请求与JSON内容 === <syntaxhighlight lang="csharp"> var user = new { Name = "John", Age = 30 }; string json = JsonSerializer.Serialize(user); using (var content = new StringContent(json, Encoding.UTF8, "application/json")) using (HttpClient client = new HttpClient()) { var response = await client.PostAsync("https://api.example.com/users", content); if (response.IsSuccessStatusCode) { var responseJson = await response.Content.ReadAsStringAsync(); Console.WriteLine($"服务器响应: {responseJson}"); } } </syntaxhighlight> === 处理不同响应类型 === <syntaxhighlight lang="csharp"> // 处理JSON响应 var response = await client.GetAsync("https://api.example.com/data"); if (response.IsSuccessStatusCode) { var data = await response.Content.ReadFromJsonAsync<MyDataClass>(); Console.WriteLine($"Received: {data}"); } // 处理二进制数据 var imageResponse = await client.GetAsync("https://example.com/image.png"); if (imageResponse.IsSuccessStatusCode) { byte[] imageData = await imageResponse.Content.ReadAsByteArrayAsync(); File.WriteAllBytes("downloaded.png", imageData); } </syntaxhighlight> == 最佳实践 == === HttpClient生命周期管理 === HttpClient设计为可重用,不应为每个请求创建新实例。最佳实践包括: * 在应用程序生命周期内重用单个HttpClient实例 * 或使用'''IHttpClientFactory'''(在ASP.NET Core中) === 超时设置 === <syntaxhighlight lang="csharp"> var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) // 设置30秒超时 }; </syntaxhighlight> === 取消支持 === <syntaxhighlight lang="csharp"> var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromSeconds(10)); // 10秒后取消 try { var response = await client.GetAsync("https://slow-api.example.com", cts.Token); // 处理响应... } catch (TaskCanceledException) { Console.WriteLine("请求已取消"); } </syntaxhighlight> == 实际应用案例 == === 天气API客户端 === <syntaxhighlight lang="csharp"> public class WeatherService { private readonly HttpClient _httpClient; public WeatherService(HttpClient httpClient) { _httpClient = httpClient; _httpClient.BaseAddress = new Uri("https://api.weatherapi.com/v1/"); } public async Task<WeatherData> GetCurrentWeatherAsync(string location) { var response = await _httpClient.GetAsync($"current.json?key=YOUR_API_KEY&q={location}"); response.EnsureSuccessStatusCode(); return await response.Content.ReadFromJsonAsync<WeatherData>(); } } // 使用示例 var weatherService = new WeatherService(new HttpClient()); var weather = await weatherService.GetCurrentWeatherAsync("London"); Console.WriteLine($"当前温度: {weather.Current.TempC}°C"); </syntaxhighlight> === 文件下载进度报告 === <syntaxhighlight lang="csharp"> public async Task DownloadFileWithProgressAsync(string fileUrl, string localPath, IProgress<double> progress) { using (var client = new HttpClient()) { // 只获取头部信息来确定内容长度 using (var response = await client.GetAsync(fileUrl, HttpCompletionOption.ResponseHeadersRead)) { response.EnsureSuccessStatusCode(); var totalBytes = response.Content.Headers.ContentLength ?? -1L; var receivedBytes = 0L; using (var contentStream = await response.Content.ReadAsStreamAsync()) using (var fileStream = new FileStream(localPath, FileMode.Create)) { var buffer = new byte[8192]; var isMoreToRead = true; do { var read = await contentStream.ReadAsync(buffer, 0, buffer.Length); if (read == 0) { isMoreToRead = false; } else { await fileStream.WriteAsync(buffer, 0, read); receivedBytes += read; if (totalBytes > 0) { progress.Report((double)receivedBytes / totalBytes); } } } while (isMoreToRead); } } } } // 使用示例 var progress = new Progress<double>(p => Console.WriteLine($"下载进度: {p:P}")); await DownloadFileWithProgressAsync("https://example.com/largefile.zip", "largefile.zip", progress); </syntaxhighlight> == 性能考虑 == === 连接池 === HttpClient内部使用连接池来重用HTTP连接。可以通过'''ServicePointManager'''进行配置: <syntaxhighlight lang="csharp"> ServicePointManager.DefaultConnectionLimit = 20; // 增加默认连接限制 </syntaxhighlight> === HTTP/2 支持 === 从.NET Core 3.0开始,HttpClient支持HTTP/2协议: <syntaxhighlight lang="csharp"> var client = new HttpClient() { DefaultRequestVersion = HttpVersion.Version20 }; </syntaxhighlight> == 常见问题与解决方案 == {| class="wikitable" |- ! 问题 !! 解决方案 |- | '''Socket耗尽''' || 重用HttpClient实例或使用IHttpClientFactory |- | '''DNS变更不生效''' || 设置HttpClient的BaseAddress或使用HttpClientHandler的PooledConnectionLifetime |- | '''大文件下载内存问题''' || 使用流式处理(ReadAsStreamAsync)而非缓冲(ReadAsByteArrayAsync) |- | '''SSL/TLS错误''' || 配置正确的SecurityProtocol或处理证书验证 |} == 总结 == C#中的HTTP客户端功能强大且灵活,从简单的GET请求到复杂的API交互都能胜任。现代应用程序应优先使用HttpClient类,遵循最佳实践来确保性能、可靠性和安全性。通过合理配置和错误处理,可以构建健壮的HTTP通信组件,满足各种网络编程需求。 [[Category:编程语言]] [[Category:C Sharp]] [[Category:C Sharp 网络编程]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)