简体   繁体   中英

Deserialize Json with an unnamed object collection

I've been searching for any solution to deserialize my Json into C# classes. I've done this so many times, but now I've come across a specific format which I don't know how to handle.

{
"32": {
    "name": "Basic",
    "data": {
        "value": null,
        "type": "empty",
        "supported": {
            "value": true,
            "type": "bool",
            "invalidateTime": 1520421448,
            "updateTime": 1520421449
        },
        "version": {
            "value": 1,
            "type": "int",
            "invalidateTime": 1520421448,
            "updateTime": 1520421449
        },
        "security": {
            "value": false,
            "type": "bool",
            "invalidateTime": 1520421448,
            "updateTime": 1520421449
        },
        "invalidateTime": 1520421448,
        "updateTime": 1520421449
    }
}

As you can see "value", "type", "invalidateTime" and "updateTime" are repetitive within their containers.

I've created a class "DataProperty"

public class DataProperty
{
    [JsonProperty("value")]
    public string Value { get; set; }

    [JsonProperty("type")]
    public string Type { get; set; }

    [JsonProperty("invalidateTime")]
    public string InvalidateTime { get; set; }

    [JsonProperty("updateTime")]
    public string UpdateTime { get; set; }
}

And a class "DataClass" => I know, needs renaming

public class DataClass
{
    [JsonProperty]
    public DataProperty Data { get; set; }

    [JsonProperty]
    public Dictionary<string,DataProperty> SubProperties { get; set; }
}

I started testing deserializing bottom up from "DataProperty" and ran into problems when deserializing the "data" entity within the json so I didn't develop the parent classes yet but submitted a bigger part of the json for overview. My problem starts when the dictionary part is not in a separate named container and I don't know how to handle this. I made a property "SubProperties" which I'm not feeling proud about, but not knowing what to do.

Below here, I will copy some lines if anyone wants to test.

string testdata = "{\"data\": {\r\n  \"value\": null,\r\n  \"type\": \"empty\",\r\n  \"supported\": {\r\n    \"value\": true,\r\n    \"type\": \"bool\",\r\n    \"invalidateTime\": 1520420777,\r\n    \"updateTime\": 1520420746\r\n  },\r\n  \"version\": {\r\n    \"value\": 1,\r\n    \"type\": \"int\",\r\n    \"invalidateTime\": 1520420777,\r\n    \"updateTime\": 1520420746\r\n  },\r\n  \"security\": {\r\n    \"value\": false,\r\n    \"type\": \"bool\",\r\n    \"invalidateTime\": 1520420745,\r\n    \"updateTime\": 1520420746\r\n  },\r\n  \"interviewDone\": {\r\n    \"value\": true,\r\n    \"type\": \"bool\",\r\n    \"invalidateTime\": 1520420745,\r\n    \"updateTime\": 1520420777\r\n  },\r\n  \"interviewCounter\": {\r\n    \"value\": 9,\r\n    \"type\": \"int\",\r\n    \"invalidateTime\": 1520420745,\r\n    \"updateTime\": 1520420749\r\n  },\r\n  \"level\": {\r\n    \"value\": 255,\r\n    \"type\": \"int\",\r\n    \"invalidateTime\": 1520420776,\r\n    \"updateTime\": 1520420777\r\n  },\r\n  \"invalidateTime\": 1520420777,\r\n  \"updateTime\": 1520420746\r\n}}"
DataClass dat = JsonConvert.DeserializeObject<DataClass>(testdata);

Thanks in advance for your time.

Checkout json2csharp since it has the Generate with QuickType option. This is very helpful for those who doesn't want to manually generate the models for their JSON strings.

JSON:

{
  "32": {
    "name": "Basic",
    "data": {
      "value": null,
      "type": "empty",
      "supported": {
        "value": true,
        "type": "bool",
        "invalidateTime": 1520421448,
        "updateTime": 1520421449
      },
      "version": {
        "value": 1,
        "type": "int",
        "invalidateTime": 1520421448,
        "updateTime": 1520421449
      },
      "security": {
        "value": false,
        "type": "bool",
        "invalidateTime": 1520421448,
        "updateTime": 1520421449
      },
      "invalidateTime": 1520421448,
      "updateTime": 1520421449
    }
  }
}

Generated QuickType Code:

// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
//    using QuickType;
//
//    var welcome = Welcome.FromJson(jsonString);

namespace QuickType
{
    using System;
    using System.Collections.Generic;

    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public partial class Welcome
    {
        [JsonProperty("32")]
        public The32 The32 { get; set; }
    }

    public partial class The32
    {
        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("data")]
        public Data Data { get; set; }
    }

    public partial class Data
    {
        [JsonProperty("value")]
        public object Value { get; set; }

        [JsonProperty("type")]
        public string Type { get; set; }

        [JsonProperty("supported")]
        public Security Supported { get; set; }

        [JsonProperty("version")]
        public Version Version { get; set; }

        [JsonProperty("security")]
        public Security Security { get; set; }

        [JsonProperty("invalidateTime")]
        public long InvalidateTime { get; set; }

        [JsonProperty("updateTime")]
        public long UpdateTime { get; set; }
    }

    public partial class Security
    {
        [JsonProperty("value")]
        public bool Value { get; set; }

        [JsonProperty("type")]
        public string Type { get; set; }

        [JsonProperty("invalidateTime")]
        public long InvalidateTime { get; set; }

        [JsonProperty("updateTime")]
        public long UpdateTime { get; set; }
    }

    public partial class Version
    {
        [JsonProperty("value")]
        public long Value { get; set; }

        [JsonProperty("type")]
        public string Type { get; set; }

        [JsonProperty("invalidateTime")]
        public long InvalidateTime { get; set; }

        [JsonProperty("updateTime")]
        public long UpdateTime { get; set; }
    }

    public partial class Welcome
    {
        public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, QuickType.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this Welcome self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
    }

    internal class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters = { 
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM