Search code examples
c#jsongdalsystem.text.json

Deserialize JSON string with empty key using System.Text.Json in C#


I use a 3rd party tool (gdalinfo) to return some statistics about a file.
Part of this JSON looks like this:

"bands":[
{
  "band":1,
  "block":[
    177,
    1
  ],
  "type":"Float32",
  "colorInterpretation":"Gray",
  "min":-1.073,
  "max":0.22,
  "minimum":-1.073,
  "maximum":0.22,
  "mean":-0.415,
  "stdDev":0.31,
  "noDataValue":1.70141e+38,
  "metadata":{
    "":{
      "STATISTICS_MAXIMUM":"0.21961125731468",
      "STATISTICS_MEAN":"-0.41532343315844",
      "STATISTICS_MINIMUM":"-1.0734000205994",
      "STATISTICS_STDDEV":"0.31004968682638",
      "STATISTICS_VALID_PERCENT":"41.81"
    }
  }
}
]

My problem is with the metadata tag.
I think it is a dictionary, but the empty key makes it very difficult.
This is my Band class:

public class Band
{
    public int band { get; set; }
    public int[] block { get; set; }
    public string type { get; set; }
    public string colorInterpretation { get; set; }
    public float min { get; set; }
    public float max { get; set; }
    public float minimum { get; set; }
    public float maximum { get; set; }
    public float mean { get; set; }
    public float stdDev { get; set; }
    public float noDataValue { get; set; }
    public BandMetadata metadata { get; set; }
}

And this is my BandMetadata class:

public class BandMetadata
{
    [JsonPropertyName("")]
    public IDictionary<string, BandStatistics>? Statistics { get; set; }
}

And this is my BandStatistics class:

public class BandStatistics
{
    public string STATISTICS_MAXIMUM { get; set; }
    public string STATISTICS_MEAN { get; set; }
    public string STATISTICS_MINIMUM { get; set; }
    public string STATISTICS_STDDEV { get; set; }
    public string STATISTICS_VALID_PERCENT { get; set; }
}

I deserialize using

var result = JsonSerializer.Deserialize<GdalInfo>(json);

But result.bands[0].metadata.Statistics is always null. All other JSON is correctly parsed.
What am I doing wrong?


Solution

  • you have to fix Band class

    public class Band
    {
        //other properties
        public Dictionary<string, BandStatistics>? metadata { get; set; }
    }
    

    and dictionary data

    BandStatistics bandStatistics = result.bands[0].metadata[""];
    

    or maybe

    BandStatistics bandStatistics = result.bands[0].BandStatistics;
    
    public class Band
    {
        public BandStatistics BandStatistics { get { return metadata == null ? null : metadata[""]; } }
    
        [JsonInclude]
        public Dictionary<string, BandStatistics>? metadata {private get; init;}
    }