-1

Total beginner here.

I have a project where I need to deserialize a JSON file into C#. I've gotten most of it down fairly well. Unfortunately, there's one part of the JSON file that doesn't want to come through—probably due to the fact that the object name is not uniform and I can't seem to find a way to get the deserializer to recognize it.

{
    "version": "36",
    "releaseDate": "20220223",
    "releaseType": "Chem",
    "calibrations": {

    # OTHER OBJECTS...

    "chemCalibrations": {
        "Cal-He-Varying-hyphenated-name1": {
            "Version": "1.0",
            "Element": "He",
            "Nucleons": 4,
            "Label": 1,
            "lighting": 1,
            "scope": "A",
            # OTHER KEY-VALUE PAIRS AND SUB-ARRAYS...
        }
        "Cal-Li-Varying-hyphenated-name2" : {
            # THE SAME KEY-VALUE PAIR TYPES AS ABOVE
        }
        ...
        "Cal-Yy-Varying-hyphenated-nameX" : {
            # THE SAME KEY-VALUE PAIR TYPES AS ABOVE
        }
    }
}

So, in the JSON string above, there's a recurring object within the "chemCalibrations" object that has a varying name starting with "Cal", a hyphen, then an elemental or chemical prefix, then a bunch of other hyphenated stuff. The hyphenated stuff varies, as does the elemental/chemical prefixes. Also the number of those objects varies as well.

I've set up a namespace in C# with a bunch of public classes for these objects, but the generic name I've given to the class for the "Cal-..." objects isn't working when deserializing.

public class ChemCals
    {
        public string Version { get; set; }
        public string Element { get; set; }
        public int Nucleons { get; set; }
        public int Label { get; set; }
        public int Lighting { get; set; }
        ...
    }

public class ChemCalibrations
    {
        public ChemCals chemCals { get; set; }
    }

For a newbie, it's a head-scratcher. I'm sure there's an easy solution here, but I'm stuck. How do I ensure that the JSON deserializer populates the "ChemCals" class here from an indefinite number of varying object names? Thank you.

a3dur4n
  • 131
  • 3
  • 1
    You can implement a custom deserializer. Or deserialize it into a JObject. Then iterate them, check the names, and cast them manually. – John Mar 07 '22 at 02:06
  • Does this answer your question? [json deserialization to C# with dynamic keys](https://stackoverflow.com/questions/65727513/json-deserialization-to-c-sharp-with-dynamic-keys) – Charlieface Mar 07 '22 at 11:42
  • Had to consult with a coworker. We ended up using a JObject.Parse function to go through one by one, much like @John suggested. – a3dur4n Mar 07 '22 at 19:42

1 Answers1

2

try to use a Dictionary

Data data = JsonConvert.DeserializeObject<Data>(json);

you can convert the Dictionary to list as well

List<CalibrationItem> calibrations = data.Calibrations.ChemCalibrations.Select(c => new CalibrationItem {Name= c.Key, ChemCalibrations=c.Value}).ToList();

result

[
  {
    "Name": "Cal-He-Varying-hyphenated-name1",
    "ChemCalibrations": {
      "Version": "1.0",
      "Element": "He",
      "Nucleons": 4,
      "Label": 1,
      "lighting": 1,
      "scope": "A"
    }
  },
  {
    "Name": "Cal-Li-Varying-hyphenated-name2",
    "ChemCalibrations": {
      "Version": null,
      "Element": null,
      "Nucleons": 0,
      "Label": 0,
      "lighting": 0,
      "scope": null
    }
  },
  {
    "Name": "Cal-Yy-Varying-hyphenated-nameX",
    "ChemCalibrations": {
      "Version": null,
      "Element": null,
      "Nucleons": 0,
      "Label": 0,
      "lighting": 0,
      "scope": null
    }
  }
]

classes

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

    [JsonProperty("releaseDate")]
    public long ReleaseDate { get; set; }

    [JsonProperty("releaseType")]
    public string ReleaseType { get; set; }

    [JsonProperty("calibrations")]
    public Calibrations Calibrations { get; set; }
}
public partial class Calibrations
{
    [JsonProperty("chemCalibrations")]
    public Dictionary<string, ChemCals> ChemCalibrations { get; set; }
}

public partial class CalibrationItem
{
    public string Name {get; set;}
    public ChemCals ChemCalibrations { get; set; }
}

public class ChemCals
{
    [JsonProperty("Version")]
    public string Version { get; set; }

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

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

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

    [JsonProperty("lighting")]
    public long Lighting { get; set; }

    [JsonProperty("scope")]
    public string Scope { get; set; }
}
Serge
  • 40,935
  • 4
  • 18
  • 45