应使用 static readonly 或 DI 单例的 HttpClient,设置 Timeout≤10秒、Accept: application/json 头;用可空类型(long?、DateTimeOffset?)和 PropertyNameCaseInsensitive 适配 SpaceX API 的半结构化 JSON,分页依赖 last_id 游标并限频≥300ms。

怎么用 HttpClient 安全获取 SpaceX API 的 JSON 数据
SpaceX API(v4)是公开的 REST 接口,返回标准 JSON,但默认不带 CORS 头、无认证,也不限流——这听着方便,实际调用时容易因网络超时或服务波动失败。别直接用 WebClient 或手动拼 HttpWebRequest,HttpClient 是唯一推荐方式,且必须复用实例。
- 错误做法:每次请求都 new 一个
HttpClient→ 连接池耗尽,出现SocketException或 DNS 解析失败 - 正确做法:声明为
static readonly HttpClient,或通过 DI 注册为单例;设置Timeout(建议 10 秒以内) - 要加
Accept: application/json请求头,虽然 API 通常忽略,但某些 CDN 或代理会据此拦截非 JSON 请求 - 示例地址:
https://api.spacexdata.com/v4/launches/latest,返回单发任务数据;/launches/upcoming返回数组
反序列化时为什么 JsonSerializer.Deserialize<T> 报错“无法转换为 int”
SpaceX API 的 JSON 字段类型不严格:比如 date_unix 是数字,但 date_utc 是字符串;success 在历史数据里可能是 null,新任务才稳定为 true/false。用强类型直接映射会崩,尤其当你定义了 public int date_unix { get; set; } 却遇到字段缺失或值为 null。
- 别用
JsonPropertyName硬绑字段名后直接映射到int或DateTime—— 改用可空类型:public long? date_unix { get; set; } -
date_utc是 ISO 8601 字符串(如"2024-05-12T12:00:00.000Z"),用DateTimeOffset?最稳妥,.NET 6+ 默认支持解析 - 如果字段可能完全不存在(比如某些测试发射没填
crew),属性得设为CrewItem[]?而非CrewItem[] - 实在不想改模型,可用
JsonDocument手动读取关键字段,跳过脏数据
如何处理分页拉取全部发射记录(比如 /launches)
SpaceX API 的列表接口不返回总条数,也不支持 page=2&limit=10 这种传统分页,而是用游标(last_id)驱动。你拿到第一页响应末尾的 id,下一次请求带上 ?last_id=xxx,直到响应为空数组为止。
- 别写 for 循环硬控 100 次——API 不保证返回固定数量,某次可能只返回 1 条,也可能 20 条
- 注意响应体是 JSON 数组,不是包裹在
{ "docs": [...] }里的对象,直接反序列化成List<Launch>即可 - 连续请求间隔建议 ≥ 300ms,避免被 Cloudflare 临时封 IP(虽无明确限流文档,但实测高频触发 429)
- 缓存
last_id到本地文件或数据库,断点续传比重跑快得多
为什么用 System.Text.Json 比 Newtonsoft.Json 更省心
SpaceX API 返回的 JSON 结构简单、无循环引用、无特殊日期格式(全是 ISO 8601 或 Unix 时间戳),System.Text.Json 原生支持足够用,而且启动快、内存占用低。Newtonsoft 虽灵活,但在 .NET 6+ 项目里纯属增加依赖和冷启动开销。
- 别碰
TypeNameHandling或ReferenceLoopHandling—— SpaceX 数据里没有这些 - 若需忽略大小写匹配字段名,用
JsonSerializerOptions.PropertyNameCaseInsensitive = true,比写一堆[JsonProperty("date_utc")]干净 - 遇到字段名含连字符(如
fairings_reused),直接按 C# 命名习惯写public bool? FairingsReused { get; set; },配合PropertyNameCaseInsensitive就能自动对齐 - 性能差异明显:10MB 的 launches.json,
System.Text.Json反序列化比 Newtonsoft 快约 35%,GC 压力小一半
真正麻烦的从来不是解析 JSON,而是处理 API 返回的“半结构化”现实:字段可空、类型漂移、分页逻辑藏在响应体里、没有文档说明字段何时出现。盯紧响应样本,别信接口文档写的“必填”。









