当第一个项目是要遵循的项目数时,如何反序列化对象数组

时间:2014-09-27 17:16:21

标签: c# json json.net

将json反序列化为c#-objects时出现以下问题。

我有一个json-string,就像这样:

string data = 
@"{
    'response':
        [
            3,
            {
                'id': 1, 
                'name': 'john'
            },
            {
                'id': 1, 
                'name': 'john'
            },
            {
                'id': 1, 
                'name': 'john'
            }
        ]
 }";

用于反序列化的类:

class Response 
{
    [JsonProperty(PropertyName = "response")]
    Item[] Items {get; set; }
}

class Item
{
    [JsonProperty(PropertyName = "id")]
    public int Id{get; set; }


    [JsonProperty(PropertyName = "name")]
    public int Id{get; set; }
}

然后我尝试反序列化它:

 var res = JsonConvert.DeserializeObject<Response>(data);

反序列化会引发一个异常,并显示以下消息:“将值3转换为'Item'时出错。路径'响应[0]',第1行,第19位。”  Obvioiusly它发生,因为数据字符串中的数组'响应'包含描述响应长度的文字“3”。我想知道,如果不通过json.net编写自定义反序列化逻辑,我可以正确地进行反序列化吗?或者我需要创建自定义反序列化逻辑?

2 个答案:

答案 0 :(得分:3)

首先,你的模型应该稍微纠正一下

public class Response
{
    [JsonProperty(PropertyName = "response")]
    Item[] Items { get; set; }
}

public class Item
{
    [JsonProperty(PropertyName = "id")]
    public int Id { get; set; }


    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; }
}

如果从json中删除3,则此反序列化将正常工作

var result = JsonConvert.DeserializeObject<Response>(json);

如果它来自服务器,您无法控制它,那么您可以编写自定义转换器

public class CustomConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Item);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.Value is long)
        {
            reader.Read(); //Skip this 3
            serializer.Converters.Remove(this); //avoid infinite recursion
        }
        return serializer.Deserialize<Item>(reader);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

并反序列化为

var result = JsonConvert.DeserializeObject<Response>(json, new CustomConverter());

您甚至可以使用Linq获取Items

的列表
var items = JObject.Parse(json)["response"]
                .Skip(1)
                .OfType<JObject>()
                .Select(j=>j.ToObject<Item>())
                .ToList();

答案 1 :(得分:0)

另一种方法,

   class Response
    {

    [JsonProperty(PropertyName = "response")]
    public dynamic Items { get; set; }
    }


    var des = JsonConvert.DeserializeObject<Response>(data);
    var result = (des.Items as IEnumerable<Newtonsoft.Json.Linq.JToken>)
              .Select(delegate(JToken j){

        if (j.Type == JTokenType.Integer)
            return j.Value<int>();

        return JsonConvert.DeserializeObject<object>(j.ToString());

    }).ToList();

    var one = JsonConvert.DeserializeObject<Item>(result[1].ToString());