JSON Newtonsoft C# 反序列化数组

Posted

技术标签:

【中文标题】JSON Newtonsoft C# 反序列化数组【英文标题】:JSON Newtonsoft C# deserialize array 【发布时间】:2021-10-13 10:26:42 【问题描述】:

我有以下 json,但无法反序列化 usernames

来源

[
  
    "id": 116,
    "FUNId": "UPmAkP",
    "status": "active",
    "usernames": "[\"user\":\"lalala1\",\"alive\":true,\"number\":\"00\",\"user\":\"lalala2\",\"alive\":true,\"number\":\"36\",\"user\":\"lalala3\",\"alive\":false,\"number\":\"18\"]",
    "startRegistration": "1624763432000",
    "startPlay": "1624772732000",
    "end": "1624773632000"
  
] 

模型类

public class JSON

    [JsonProperty("startRegistration"), JsonConverter(typeof(UnixTimestampConverter))]
    public DateTime startRegistration  get; set; 
    
    [JsonProperty("startPlay"), JsonConverter(typeof(UnixTimestampConverter))]
    public DateTime startPlay get; set; 
    
    [JsonProperty("end"), JsonConverter(typeof(UnixTimestampConverter))]
    public DateTime ended  get; set; 
    
    [JsonProperty("usernames"), JsonConverter(typeof(JsonToArrayConverter<Players>))]
    public Players[] usernames  get; set; 

public class Players

    [JsonProperty("user")]
    public string user  get; set; 
    
    [JsonProperty("alive")]
    public bool alive  get; set; 
                  
    [JsonProperty("number")]
    public string number  get; set; 

转换器

public class JsonToArrayConverter<Players> : CustomCreationConverter<Players[]>

    public override Players[] Create(Type objectType)
    
        return new Players[0];
    

    public override object ReadJson(JsonReader reader, Type objectType, object
        existingValue, JsonSerializer serializer)
    
        if (reader.TokenType == JsonToken.StartArray)
        
            object result = serializer.Deserialize(reader, objectType);
            return result;
        
        else
        
            var resultObject = serializer.Deserialize<Players>(reader);
            return new Players[]  resultObject ;
        
    

class UnixTimestampConverter : JsonConverter

    static readonly DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

    public override bool CanConvert(Type objectType)
    
        return typeof(DateTime).IsAssignableFrom(objectType);
    

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    
        long timestamp = serializer.Deserialize<long>(reader);
        return unixEpoch.AddMilliseconds(timestamp+10800000);
    

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    
        var date = (DateTime)value;
        var utcDate = date.ToUniversalTime();
        var timestamp = (int)(utcDate - unixEpoch).TotalSeconds;

        serializer.Serialize(writer, timestamp);
    

问题

当我尝试这个时:

var foos = JsonConvert.DeserializeObject<List<JSON>>(FIRST); 

然后我得到这个错误:

Newtonsoft.Json.JsonSerializationException: "错误转换值 ["user":"lalala1","alive":true,"number":"00","user":"lalal a2","alive":true,"number":"36","user":"lalala3","alive":fa lse,"number":"18"]

【问题讨论】:

考虑列表而不是数组。试试:public List&lt;Players&gt; usernames get; set; @RyanWilson 我已经尝试过这样做,只将类命名为 Players。能给我个sn-p代码吗? 你能改变 JSON 的形状吗?理想情况下,usernames 属性应该是一个实际的数组,而不是 JSON 字符串表示形式。 【参考方案1】:
[JsonProperty("usernames")]
private string UserNamesJson  get; set; 

public UserName[] UserNames

    get => JsonConvert.DeserializeObject<UserName[]>(UserNamesJson);
    set => UserNames = value;

这段代码运行良好。

【讨论】:

你确定UserNamesJsonprivate 是的,基本上它是双序列化的。你真的应该从源头上修复它【参考方案2】:

你有一个错误,从用户名数组中删除“\”

"usernames": ["user":"lalala1","alive":true,"number":"00","user":"lalala2","alive":true,"number":"36","user":"lalala3","alive":false,"number":"18"]

现在可以反序列化了

var jsonDeserialized = JsonConvert.DeserializeObject<Data[]>(json); 

你的课程应该是

public class Username

    public string user  get; set; 
    public bool alive  get; set; 
    public string number  get; set; 


public class Data

    public int id  get; set; 
    public string FUNId  get; set; 
    public string status  get; set; 
    public List<Username> usernames  get; set; 
    public string startRegistration  get; set; 
    public string startPlay  get; set; 
    public string end  get; set; 

并修复您的 json。应该是

[
   
      "id":116,
      "FUNId":"UPmAkP",
      "status":"active",
      "usernames":[
         
            "user":"lalala1",
            "alive":true,
            "number":"00"
         ,
         
            "user":"lalala2",
            "alive":true,
            "number":"36"
         ,
         
            "user":"lalala3",
            "alive":false,
            "number":"18"
         
      ],
      "startRegistration":"1624763432000",
      "startPlay":"1624772732000",
      "end":"1624773632000"
   
]

【讨论】:

谢谢。但不需要删除任何东西。寻找我的答案。

以上是关于JSON Newtonsoft C# 反序列化数组的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中从 JSON 反序列化数组

C# json反序列化 对象中嵌套数组 (转载)

C# Newtonsoft.Json 解析多嵌套json 进行反序列化

C# Newtonsoft.Json 解析多嵌套json 进行反序列化

C#中使用Newtonsoft.Json序列化和反序列化自定义类对象

C# Newtonsoft JSON:反序列化和跳过对象名称