共计 1796 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点
在 VS2010 时代,.NET Framework 对 JSON 的原生支持相当有限。默认工具链中缺少现代 WebAPI 客户端工具(如 HttpClient),开发者不得不依赖基础类库实现 HTTP 通信。这导致三个典型问题:

- 缺乏内置 JSON 序列化 / 反序列化工具(Newtonsoft.Json 需手动引入)
- WebRequest 类设计陈旧,异步模式复杂
- 没有默认设置 JSON 内容类型的快捷方式
技术选型
当时可选的方案主要有两种:
- HttpWebRequest
- 优点:细粒度控制请求过程,支持流式处理
-
缺点:代码冗余度高,需手动管理连接生命周期
-
WebClient
- 优点:简化常见操作,自动处理基础资源释放
- 缺点:灵活性差,难以定制请求细节
特别注意:WebRequest 已在后续版本被标记为过时(obsolete),新项目应避免使用
核心实现(HttpWebRequest 方案)
以下是分步骤实现过程:
- 创建基础请求对象
- 配置请求方法和内容类型
- 处理响应流并转换结果
- 资源释放保障
// 完整示例代码
public string GetJsonData(string url)
{
HttpWebRequest request = null;
Stream responseStream = null;
StreamReader reader = null;
try
{
// 1. 创建请求实例
request = (HttpWebRequest)WebRequest.Create(url);
// 2. 关键配置项
request.Method = "GET";
request.ContentType = "application/json";
request.Accept = "application/json"; // 明确声明期望返回类型
// 3. 获取响应
using (var response = (HttpWebResponse)request.GetResponse())
{responseStream = response.GetResponseStream();
reader = new StreamReader(responseStream, Encoding.UTF8);
return reader.ReadToEnd();}
}
finally
{
// 4. 资源清理(按创建逆序释放)reader?.Dispose();
responseStream?.Dispose();
request?.Abort();}
}
性能优化技巧
对于高频调用的场景,建议采用以下优化:
- 使用 MemoryStream 缓存响应数据(减少 GC 压力)
- 重用 Encoding 实例(避免重复创建)
- 设置合理的 Timeout(默认 100 秒过长)
优化后的关键代码段:
// 静态字段提升性能
private static readonly Encoding utf8 = Encoding.UTF8;
// 在 try 块内替换为:using (var ms = new MemoryStream())
{response.GetResponseStream().CopyTo(ms);
return utf8.GetString(ms.ToArray());
}
避坑指南
实战中容易遇到的三个典型问题:
- HTTP 406 错误
- 原因:未设置 Accept 请求头
-
解决:显式添加
request.Accept = "application/json" -
证书验证失败
- 原因:HTTPS 站点证书不被信任
-
解决:在请求前添加
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, errors) => true;(仅测试环境使用) -
中文乱码
- 原因:响应头未声明编码方式
- 解决:强制使用 UTF8 编码读取流
延伸思考
对于长期维护的项目,建议:
- 封装为泛型方法,支持自动反序列化
- 添加重试机制(针对网络波动)
- 考虑使用 WCF 作为替代方案(但需注意其配置复杂性)
调试验证技巧
快速验证请求是否成功:
- 使用 Fiddler 抓包检查实际发出的请求头
- 在代码中打印响应状态码:
Console.WriteLine(response.StatusCode); - 测试阶段可以先返回原始字符串,确认数据完整后再处理
结语
虽然现代开发环境已提供更便捷的工具,但理解这些底层实现仍然有价值。当遇到遗留系统维护或特殊限制场景时,这套方案仍能可靠工作。建议根据实际项目需求,在功能完整性和代码简洁性之间找到平衡点。
正文完
