NewtonSoft Json反序列化属性列表作为对象数组

Gra*_*amB 5 .net json.net

我有一个奇怪的Json结果集,该结果集具有重复(但可变)属性,我需要将其转换为对象类型的数组,例如

"result": {
    "documents": {
        "abcd": {
            "propertyX": 0
            "propertyY": "A"
        },
        "efgh": {
            "propertyX": 5
            "propertyY": "B"
        },
        "ijkl": {
            "propertyX": 2
            "propertyY": "C"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想做的是让Result对象具有document属性,并且该属性具有一个“ items”数组。每个项目对象将包含“ propertyX”,“ propertyY”等。不幸的是,“ abcd”,“ efgh”等是项目的随机列表,但它们呈现为不同的属性。

有没有简单的方法可以解决此问题,或者我需要自定义转换器?

Bri*_*ers 5

是的,处理此问题的直接方法是Dictionary<string, Item>为您的documents媒体资源使用。随机文档名称将成为字典的关键字。您可以这样声明类:

class RootObject
{
    public Result Result { get; set; }
}

class Result
{
    public Dictionary<string, Item> Documents { get; set; }
}

class Item
{
    public string PropertyX { get; set; }
    public string PropertyY { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样反序列化JSON:

RootObject root = JsonConvert.DeserializeObject<RootObject>(json);
Run Code Online (Sandbox Code Playgroud)

小提琴:https : //dotnetfiddle.net/lTDGj3


如果您不想在您的班级中使用字典,而是希望使用项的数组(或列表),那么可以,则需要一个转换器。在这种情况下,您可以这样声明类:

class RootObject
{
    public Result Result { get; set; }
}

class Result
{
    [JsonConverter(typeof(DocumentListConverter))]
    public List<Item> Documents { get; set; }
}

class Item
{
    public string Name { get; set; }
    public string PropertyX { get; set; }
    public string PropertyY { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

文档列表的自定义转换器类如下所示:

class DocumentListConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<Item>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        List<Item> items = new List<Item>();
        foreach (JProperty prop in jo.Properties())
        {
            Item item = prop.Value.ToObject<Item>();
            item.Name = prop.Name;
            items.Add(item);
        }
        return items;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

您将以与以前相同的方式反序列化:

RootObject root = JsonConvert.DeserializeObject<RootObject>(json);
Run Code Online (Sandbox Code Playgroud)

小提琴:https : //dotnetfiddle.net/xWRMGP