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

使用NewtonSoft反序列化JSON时无法将字符串转换为对象

解决NewtonSoft反序列化时字符串转对象的问题

看你给出的JSON数据,问题核心出在user字段上——它的值是一个带转义符的JSON字符串(比如包含\r\n和转义双引号),而非直接的JSON对象。默认情况下NewtonSoft会把它当成普通字符串处理,但你应该是想把它解析成对应的User实体,所以才会触发转换错误。

下面给你几种可行的解决办法:

方法1:修改JSON源(最直接,若能控制源头)

如果可以调整生成这个JSON的上游服务,把user字段的外层引号和转义符去掉,让它直接成为一个JSON对象:

原JSON的user片段:
"user":"{\r\n \"Active\": true,\r\n \"DisplayName\": \"Sakib Hasan\",...}"
修改后:
"user":{\r\n "Active": true,\r\n "DisplayName": "Sakib Hasan",...}

这样直接用常规的类结构反序列化就不会有问题了。

方法2:分两步反序列化(无需修改JSON)

如果没法改动JSON源,我们可以先把user当成字符串接收,再单独解析这个字符串为User对象:

步骤1:定义临时接收类和目标User类

// 临时类:用来接收第一次反序列化的结果,user字段设为string类型
public class TempTokenResponse
{
    public string access_token { get; set; }
    public string token_type { get; set; }
    public int expires_in { get; set; }
    public string refresh_token { get; set; }
    
    // 带点的字段需要用JsonProperty映射C#属性名
    [JsonProperty(".issued")]
    public string Issued { get; set; }
    
    [JsonProperty(".expires")]
    public string Expires { get; set; }
    
    public string ip_address { get; set; }
    public string client_id { get; set; }
    public string user { get; set; }
}

// 你的User实体类
public class User
{
    public bool Active { get; set; }
    public string DisplayName { get; set; }
    public string Email { get; set; }
    public bool EmailVarified { get; set; }
    public string Language { get; set; }
    public string PhoneNumber { get; set; }
    public string ProfileImageUrl { get; set; }
    public List<string> Roles { get; set; }
}

步骤2:执行两次反序列化

// 第一步:把整个JSON反序列化成临时类
var tempResult = JsonConvert.DeserializeObject<TempTokenResponse>(yourJsonString);

// 第二步:把user字符串单独解析成User对象
var user = JsonConvert.DeserializeObject<User>(tempResult.user);

// 后续可将user赋值给最终的响应类对象,或直接使用

方法3:自定义JsonConverter(一键自动处理)

如果你想一步完成反序列化,可以自定义转换器,让NewtonSoft自动把user的字符串解析成对象:

步骤1:实现自定义转换器

public class StringToObjectConverter<T> : JsonConverter<T>
{
    public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 若读取到的是字符串,就将其反序列化为目标类型
        if (reader.TokenType == JsonToken.String)
        {
            var jsonStr = reader.Value.ToString();
            return JsonConvert.DeserializeObject<T>(jsonStr);
        }
        // 否则按常规逻辑处理
        return serializer.Deserialize<T>(reader);
    }

    public override void WriteJson(JsonWriter writer, T value, JsonSerializer serializer)
    {
        // 若需要序列化回去,可在此将对象转为字符串
        var jsonStr = JsonConvert.SerializeObject(value);
        writer.WriteValue(jsonStr);
    }
}

步骤2:在目标类的user属性上应用转换器

public class TokenResponse
{
    public string access_token { get; set; }
    public string token_type { get; set; }
    public int expires_in { get; set; }
    public string refresh_token { get; set; }
    
    [JsonProperty(".issued")]
    public string Issued { get; set; }
    
    [JsonProperty(".expires")]
    public string Expires { get; set; }
    
    public string ip_address { get; set; }
    public string client_id { get; set; }
    
    // 给user属性绑定自定义转换器
    [JsonConverter(typeof(StringToObjectConverter<User>))]
    public User user { get; set; }
}

// User类同方法2定义
public class User
{
    public bool Active { get; set; }
    public string DisplayName { get; set; }
    public string Email { get; set; }
    public bool EmailVarified { get; set; }
    public string Language { get; set; }
    public string PhoneNumber { get; set; }
    public string ProfileImageUrl { get; set; }
    public List<string> Roles { get; set; }
}

步骤3:直接反序列化

var response = JsonConvert.DeserializeObject<TokenResponse>(yourJsonString);
// 此时response.user已经是解析完成的User对象

另外注意:你提供的JSON中Roles数组是截断状态([\r\n \"anonymous\",\r...}),实际使用时要确保JSON完整,否则也会导致反序列化失败哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:18:21