You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#反序列化Web API返回的BadRequest错误响应?

解决Web API错误JSON反序列化的问题

我帮你搞定这个棘手的反序列化问题!这种带特殊空键的ModelState结构确实容易踩坑,咱们一步步拆解解决。

首先,先明确你收到的错误JSON的特殊之处:ModelState里有一个空字符串作为键,对应的值是包含具体错误信息的数组。先把这个JSON结构再理清楚:

{ 
  "$id":"1", 
  "Message":"The request is invalid.", 
  "ModelState": { 
    "$id":"2", 
    "": { 
      "$id":"3", 
      "$values": ["Name username@gmail.com is already taken."] 
    } 
  } 
}

下面给你两种可行的解决方案,按需选择:


方案一:强类型类(推荐,类型安全)

创建对应JSON结构的实体类,关键是用JsonProperty特性指定空字符串的键,让序列化器能正确匹配:

using Newtonsoft.Json;
using System.Collections.Generic;

// 顶层错误响应类
public class ApiErrorResponse
{
    [JsonProperty("$id")]
    public string Id { get; set; }
    
    public string Message { get; set; }
    
    // 用字典接收ModelState的所有键值对,包括空字符串键
    public Dictionary<string, ModelStateError> ModelState { get; set; }
}

// ModelState中每个键对应的错误结构
public class ModelStateError
{
    [JsonProperty("$id")]
    public string Id { get; set; }
    
    [JsonProperty("$values")]
    public List<string> ErrorMessages { get; set; }
}

然后反序列化并提取错误信息:

// 假设responseString是你从API获取到的JSON字符串
var errorResponse = JsonConvert.DeserializeObject<ApiErrorResponse>(responseString);

// 提取空键对应的错误信息(这里用FirstOrDefault避免空引用)
var specificError = errorResponse.ModelState[""]?.ErrorMessages?.FirstOrDefault();

// 现在specificError就是"Name username@gmail.com is already taken."
// 可以直接展示给用户

这种方式的好处是类型安全,后续如果API返回的结构有变化,编译器能帮你提前发现问题。


方案二:动态类型(快速验证)

如果只是临时调试或者不想创建实体类,可以用动态类型快速提取错误:

using Newtonsoft.Json;

var dynamicError = JsonConvert.DeserializeObject<dynamic>(responseString);
var errorMessage = dynamicError.ModelState[""].$values[0].ToString();

这种方式简单直接,但没有类型检查,适合快速验证场景。


注意事项(针对System.Text.Json用户)

如果你用的是.NET Core/.NET 5+自带的System.Text.Json,需要注意配置序列化选项,确保能正确处理空键和大小写:

using System.Text.Json;

var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true, // 忽略大小写匹配
    AllowTrailingCommas = true // 可选,防止JSON有多余逗号
};

var errorResponse = JsonSerializer.Deserialize<ApiErrorResponse>(responseString, options);
var specificError = errorResponse.ModelState[""]?.ErrorMessages?.FirstOrDefault();

这样就能完美解决你遇到的反序列化问题啦!

内容的提问来源于stack exchange,提问作者Amokachi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:49:39