Home > Back-end >  Trouble deserializing JSON array with random root element
Trouble deserializing JSON array with random root element

Time:09-29

I have this json:

{
  "f6a1ad82-4b5f-430d-92a0-817927f5beaa": [
    {
      "id": "5a9d3ae5fcf53960035643a7",
      "state": "RUNNING",
      "started_at": "2021-09-20T10:15:49.613Z",
      "detailed_message": null,
      "message_input": {
        "title": "Windows Event Logs",
        "global": true,
        "name": "GELF TCP",
        "content_pack": null,
        "created_at": "2018-03-05T12:48:16.447Z",
        "type": "org.graylog2.inputs.gelf.tcp.GELFTCPInput",
        "creator_user_id": "adminuser",
        "attributes": {
          "recv_buffer_size": 1048576,
          "tcp_keepalive": false,
          "use_null_delimiter": true,
          "tls_client_auth_cert_file": "",
          "bind_address": "0.0.0.0",
          "tls_cert_file": "",
          "decompress_size_limit": 8388608,
          "port": 12200,
          "tls_key_file": "",
          "tls_enable": false,
          "tls_key_password": "",
          "max_message_size": 2097152,
          "tls_client_auth": "disabled",
          "override_source": null
        },
        "static_fields": {},
        "node": null,
        "id": "5a9d3ae5fcf123453a7"
      }
    },
    {
      "id": "5a94423bfcf53920285e3a3b",
      "state": "RUNNING",
      "started_at": "2021-09-20T10:15:49.609Z",
      "detailed_message": null,
      "message_input": {
        "title": "Apache Filebeat",
        "global": true,
        "name": "Beats (deprecated)",
        "content_pack": null,
        "created_at": "2018-02-26T17:50:30.581Z",
        "type": "org.graylog.plugins.beats.BeatsInput",
        "creator_user_id": "adminuser",
        "attributes": {
          "recv_buffer_size": 1048576,
          "port": 5040,
          "tls_key_file": "",
          "tls_enable": false,
          "tls_key_password": "",
          "tcp_keepalive": false,
          "tls_client_auth_cert_file": "",
          "tls_client_auth": "disabled",
          "override_source": null,
          "bind_address": "0.0.0.0",
          "tls_cert_file": ""
        },
        "static_fields": {},
        "node": null,
        "id": "5a94423bfcf53555555e3a3b"
      }
    }
  ]
}

Using QuickType I have this class I'm attempting to deserialize into:

namespace Phono.Packages.GraylogLowLevelRESTClient.Models
{
    using System;
    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    [JsonObject]
    public partial class ClusterInputstates
    {
        [JsonProperty("f6a1ad82-4b5f-430d-92a0-817927f5beaa")]
        public NodeId[] NodeId { get; set; }
    }

    public partial class NodeId
    {
        [JsonProperty("id")]
        public string Id { get; set; }

        [JsonProperty("state")]
        public string State { get; set; }

        [JsonProperty("started_at")]
        public DateTimeOffset StartedAt { get; set; }

        [JsonProperty("detailed_message")]
        public string DetailedMessage { get; set; }

        [JsonProperty("message_input")]
        public MessageInput MessageInput { get; set; }
    }

    public partial class MessageInput
    {
        [JsonProperty("title")]
        public string Title { get; set; }

        [JsonProperty("global")]
        public bool Global { get; set; }

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

        [JsonProperty("content_pack")]
        public object ContentPack { get; set; }

        [JsonProperty("created_at")]
        public DateTimeOffset CreatedAt { get; set; }

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

        [JsonProperty("creator_user_id")]
        public string CreatorUserId { get; set; }

        [JsonProperty("attributes")]
        public Attributes Attributes { get; set; }

        [JsonProperty("static_fields")]
        public StaticFields StaticFields { get; set; }

        [JsonProperty("node")]
        public Guid? Node { get; set; }

        [JsonProperty("id")]
        public string Id { get; set; }
    }

    public partial class Attributes
    {
        [JsonProperty("recv_buffer_size", NullValueHandling = NullValueHandling.Ignore)]
        public long? RecvBufferSize { get; set; }

        [JsonProperty("tcp_keepalive", NullValueHandling = NullValueHandling.Ignore)]
        public bool? TcpKeepalive { get; set; }

        [JsonProperty("use_null_delimiter", NullValueHandling = NullValueHandling.Ignore)]
        public bool? UseNullDelimiter { get; set; }

        [JsonProperty("tls_client_auth_cert_file", NullValueHandling = NullValueHandling.Ignore)]
        public string TlsClientAuthCertFile { get; set; }

        [JsonProperty("bind_address", NullValueHandling = NullValueHandling.Ignore)]
        public string BindAddress { get; set; }

        [JsonProperty("tls_cert_file", NullValueHandling = NullValueHandling.Ignore)]
        public string TlsCertFile { get; set; }

        [JsonProperty("decompress_size_limit", NullValueHandling = NullValueHandling.Ignore)]
        public long? DecompressSizeLimit { get; set; }

        [JsonProperty("port", NullValueHandling = NullValueHandling.Ignore)]
        public long? Port { get; set; }

        [JsonProperty("tls_key_file", NullValueHandling = NullValueHandling.Ignore)]
        public string TlsKeyFile { get; set; }

        [JsonProperty("tls_enable", NullValueHandling = NullValueHandling.Ignore)]
        public bool? TlsEnable { get; set; }

        [JsonProperty("tls_key_password", NullValueHandling = NullValueHandling.Ignore)]
        public string TlsKeyPassword { get; set; }

        [JsonProperty("max_message_size", NullValueHandling = NullValueHandling.Ignore)]
        public long? MaxMessageSize { get; set; }

        [JsonProperty("tls_client_auth", NullValueHandling = NullValueHandling.Ignore)]
        public string TlsClientAuth { get; set; }

        [JsonProperty("override_source")]
        public object OverrideSource { get; set; }

        [JsonProperty("heartbeat", NullValueHandling = NullValueHandling.Ignore)]
        public long? Heartbeat { get; set; }

        [JsonProperty("prefetch", NullValueHandling = NullValueHandling.Ignore)]
        public long? Prefetch { get; set; }

        [JsonProperty("exchange_bind", NullValueHandling = NullValueHandling.Ignore)]
        public bool? ExchangeBind { get; set; }

        [JsonProperty("broker_vhost", NullValueHandling = NullValueHandling.Ignore)]
        public string BrokerVhost { get; set; }

        [JsonProperty("broker_username", NullValueHandling = NullValueHandling.Ignore)]
        public string BrokerUsername { get; set; }

        [JsonProperty("broker_port", NullValueHandling = NullValueHandling.Ignore)]
        public long? BrokerPort { get; set; }

        [JsonProperty("parallel_queues", NullValueHandling = NullValueHandling.Ignore)]
        public long? ParallelQueues { get; set; }

        [JsonProperty("broker_password", NullValueHandling = NullValueHandling.Ignore)]
        public string BrokerPassword { get; set; }

        [JsonProperty("throttling_allowed", NullValueHandling = NullValueHandling.Ignore)]
        public bool? ThrottlingAllowed { get; set; }

        [JsonProperty("exchange", NullValueHandling = NullValueHandling.Ignore)]
        public string Exchange { get; set; }

        [JsonProperty("tls", NullValueHandling = NullValueHandling.Ignore)]
        public bool? Tls { get; set; }

        [JsonProperty("routing_key", NullValueHandling = NullValueHandling.Ignore)]
        public string RoutingKey { get; set; }

        [JsonProperty("requeue_invalid_messages", NullValueHandling = NullValueHandling.Ignore)]
        public bool? RequeueInvalidMessages { get; set; }

        [JsonProperty("broker_hostname", NullValueHandling = NullValueHandling.Ignore)]
        public string BrokerHostname { get; set; }

        [JsonProperty("queue", NullValueHandling = NullValueHandling.Ignore)]
        public string Queue { get; set; }

        [JsonProperty("idle_writer_timeout", NullValueHandling = NullValueHandling.Ignore)]
        public long? IdleWriterTimeout { get; set; }

        [JsonProperty("max_chunk_size", NullValueHandling = NullValueHandling.Ignore)]
        public long? MaxChunkSize { get; set; }

        [JsonProperty("enable_cors", NullValueHandling = NullValueHandling.Ignore)]
        public bool? EnableCors { get; set; }

        [JsonProperty("force_rdns", NullValueHandling = NullValueHandling.Ignore)]
        public bool? ForceRdns { get; set; }

        [JsonProperty("store_full_message", NullValueHandling = NullValueHandling.Ignore)]
        public bool? StoreFullMessage { get; set; }

        [JsonProperty("expand_structured_data", NullValueHandling = NullValueHandling.Ignore)]
        public bool? ExpandStructuredData { get; set; }

        [JsonProperty("allow_override_date", NullValueHandling = NullValueHandling.Ignore)]
        public bool? AllowOverrideDate { get; set; }
    }

    public partial class StaticFields
    {
    }

    public partial class ClusterInputstates
    {
        public static ClusterInputstates FromJson(string json) => JsonConvert.DeserializeObject<ClusterInputstates>(json, Phono.Packages.GraylogLowLevelRESTClient.Models.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this ClusterInputstates self) => JsonConvert.SerializeObject(self, Phono.Packages.GraylogLowLevelRESTClient.Models.Converter.Settings);
    }

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

It works, but I am unable to deserialize unless I specify the first element explicitly in JsonPropery.

IE: [JsonProperty("f6a1ad82-4b5f-430d-92a0-817927f5beaa")]

In reality, this property is a GUID and subject to change all the time (as well as the possibility of multiple GUID objects in their own array).

I've tried variations of:

public Dictionary<string, NodeId[]> NodeId { get; set; }

but this either results in an exception/failure to deserialize or the object returned is null.

What am I missing?

CodePudding user response:

This was tested using Visual Studio 2019 and serialize libraries. Everything is working properly.

using Newtonsoft.Json

 var deserializedJson= JsonConvert.DeserializeObject<Dictionary<string, List<Message>>>(json);

How to use (examples)

List<Message> result =  deserializedJson.Values.FirstOrDefault();

var startedAt=result[0].StartedAt;
//or
 var startedAt=result.FirstOrDefault().StartedAt;

var  port0=result[0].MessageInput.Attributes.Port;
//or
var  port0=result.Where(r => r.Id== "5a9d3ae5fcf53960035643a7").FirstOrDefault()
.MessageInput.Attributes.Port;

var port1 = result[1].MessageInput.Attributes.Port;

ouput

2021-09-20 10:15:49 AM  00:00
12200
5040

classes

public partial class Message
    {
        [JsonProperty("id")]
        public string Id { get; set; }

        [JsonProperty("state")]
        public string State { get; set; }

        [JsonProperty("started_at")]
        public DateTimeOffset StartedAt { get; set; }

        [JsonProperty("detailed_message")]
        public object DetailedMessage { get; set; }

        [JsonProperty("message_input")]
        public MessageInput MessageInput { get; set; }
    }

    public partial class MessageInput
    {
        [JsonProperty("title")]
        public string Title { get; set; }

        [JsonProperty("global")]
        public bool Global { get; set; }

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

        [JsonProperty("content_pack")]
        public object ContentPack { get; set; }

        [JsonProperty("created_at")]
        public DateTimeOffset CreatedAt { get; set; }

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

        [JsonProperty("creator_user_id")]
        public string CreatorUserId { get; set; }

        [JsonProperty("attributes")]
        public Attributes Attributes { get; set; }

        [JsonProperty("static_fields")]
        public StaticFields StaticFields { get; set; }

        [JsonProperty("node")]
        public object Node { get; set; }

        [JsonProperty("id")]
        public string Id { get; set; }
    }

    public partial class Attributes
    {
        [JsonProperty("recv_buffer_size")]
        public long RecvBufferSize { get; set; }

        [JsonProperty("tcp_keepalive")]
        public bool TcpKeepalive { get; set; }

        [JsonProperty("use_null_delimiter", NullValueHandling = NullValueHandling.Ignore)]
        public bool? UseNullDelimiter { get; set; }

        [JsonProperty("tls_client_auth_cert_file")]
        public string TlsClientAuthCertFile { get; set; }

        [JsonProperty("bind_address")]
        public string BindAddress { get; set; }

        [JsonProperty("tls_cert_file")]
        public string TlsCertFile { get; set; }

        [JsonProperty("decompress_size_limit", NullValueHandling = NullValueHandling.Ignore)]
        public long? DecompressSizeLimit { get; set; }

        [JsonProperty("port")]
        public long Port { get; set; }

        [JsonProperty("tls_key_file")]
        public string TlsKeyFile { get; set; }

        [JsonProperty("tls_enable")]
        public bool TlsEnable { get; set; }

        [JsonProperty("tls_key_password")]
        public string TlsKeyPassword { get; set; }

        [JsonProperty("max_message_size", NullValueHandling = NullValueHandling.Ignore)]
        public long? MaxMessageSize { get; set; }

        [JsonProperty("tls_client_auth")]
        public string TlsClientAuth { get; set; }

        [JsonProperty("override_source")]
        public object OverrideSource { get; set; }
    }

    public partial class StaticFields
    {
    }
  • Related