httpclient.getfromjsonasync 默认不检查状态码,4xx/5xx 直接抛 httprequestexception;应先 ensuresuccessstatuscode 或判断 issuccessstatuscode;201/204 等需手动读取内容反序列化;动态 json 推荐 .net 6+ 的 jsonnode;httpclient 必须复用,禁用 using new;动态字段名需用 dictionary 或正则匹配;服务端响应不稳定,须全程判空或捕获 jsonexception。

HttpClient.GetFromJsonAsync 会直接抛异常?检查响应状态码
不是所有 HTTP 请求都能直接用 GetFromJsonAsync 安全解析。它默认不检查 HttpResponseMessage.StatusCode,遇到 4xx/5xx 会直接抛 HttpRequestException,而不是返回 null 或空对象。
- 务必在调用前用
EnsureSuccessStatusCode(),或手动判断response.IsSuccessStatusCode - 如果服务端返回 200 以外的成功码(比如 201、204),
GetFromJsonAsync默认不认,得自己读取response.Content.ReadAsStringAsync()再反序列化 - 别依赖 try-catch 捕获“JSON 解析失败”来兜底——那可能是网络超时、证书错误、或服务端返回了 HTML 错误页(比如 502 Bad Gateway 页面)
动态 JSON 用 System.Text.Json.JsonDocument 还是 JsonNode?
.NET 6+ 推荐用 JsonNode,比 JsonDocument 更灵活,支持动态属性访问和修改;JsonDocument 是只读、不可变的,适合只读解析且对内存敏感的场景。
-
JsonNode.Parse(jsonString)返回可索引对象,支持root["data"][0]["name"].GetValue<string>()</string> - 如果 JSON 结构完全未知,用
JsonNode+AsObject()或AsArray()判断类型,避免NullReferenceException - 注意:
JsonNode在 .NET 6+ 才有;.NET 5 及更早只能用JsonDocument+RootElement配合EnumerateObject()
HttpClient 实例该 new 还是复用?
必须复用同一个 HttpClient 实例,否则高并发下会耗尽 socket 连接,触发 SocketException: Too many open files 或 DNS 超时。
- 把
HttpClient声明为static readonly,或注册为 DI 容器中的单例(AddHttpClient()) - 不要用
using var client = new HttpClient()包裹每次请求——这是最常见也最危险的写法 - 如果需要不同 BaseAddress 或 Headers,用
HttpClientFactory创建命名客户端,而不是 new 多个实例
反序列化动态字段名(如 timestamp_1678901234)怎么处理?
System.Text.Json 默认不支持通配符键名,不能靠 [JsonPropertyName("xxx")] 硬编码。得先解析成字典或 JsonNode,再手动提取。
- 用
Dictionary<string jsonnode></string>接收顶层对象,然后遍历 Key 匹配正则^timestamp_\d+$ - 别试图用
JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase解决——它只改大小写,不处理动态前缀 - 如果字段名规律强(比如全是
data_数字),建议先node.AsObject().ToDictionary(kvp => kvp.Key, kvp => kvp.Value),再过滤 Key
动态 JSON 的坑不在解析语法,而在服务端响应的不确定性:可能突然多字段、少字段、换类型、甚至返回空字符串或 null。别假设结构稳定,每次取值前都得判空或 try-catch JsonException。










