I have a json from here https://api.nasa.gov/insight_weather/?api_key=DEMO_KEY&feedtype=json&ver=1.0 which looks like:
{
"782": {
"First_UTC": "2021-02-06T17:08:11Z",
"Last_UTC": "2021-02-07T17:47:46Z",
"Month_ordinal": 12,
"Northern_season": "late winter",
"PRE": {
"av": 721.77,
"ct": 113450,
"mn": 698.8193,
"mx": 742.2686
},
"Season": "winter",
"Southern_season": "late summer",
"WD": {
"most_common": null
}
},
"783": {
"First_UTC": "2021-02-07T17:47:46Z",
"Last_UTC": "2021-02-08T18:27:22Z",
"Month_ordinal": 12,
"Northern_season": "late winter",
"PRE": {
"av": 722.186,
"ct": 107270,
"mn": 698.7664,
"mx": 743.1983
},
"Season": "winter",
"Southern_season": "late summer",
"WD": {
"most_common": null
}
},
"sol_keys": [ "782", "783" ],
"validity_checks": { /* Some complex object */ }
}
I need only part of this information so I have created the following classes:
public class MarsWheather {
[JsonPropertyName("First_UTC")]
public DateTime FirstUTC { get; set; }
[JsonPropertyName("Last_UTC")]
public DateTime LastUTC { get; set; }
[JsonPropertyName("Season")]
[JsonConverter(typeof(JsonStringEnumConverter))]
public Season MarsSeason { get; set; }
[JsonPropertyName("PRE")]
public DataDescription AtmosphericPressure { get; set; }
}
public enum Season {
winter,
spring,
summer,
autumn
}
public class DataDescription{
[JsonPropertyName("av")]
public double Average { get; set; }
[JsonPropertyName("ct")]
public double TotalCount { get; set; }
[JsonPropertyName("mn")]
public double Minimum { get; set; }
[JsonPropertyName("mx")]
public double Maximum { get; set; }
}
The problem is that the JSON root object from NASA contains properties "validity_checks" and "sol_keys" that I don't need and want to skip. In Newton.Json I've used JObject.Parse to do this, but in System.Text.Json I want to use
JsonSerializer.DeserializeAsync<Dictionary<string, MarsWheather>>(stream, new JsonSerializerOptions { IgnoreNullValues = true });
Unfortunately, when I do I get an exception:
System.Text.Json.JsonException: The JSON value could not be converted to MarsWheather. Path: $.sol_keys | LineNumber: 120 | BytePositionInLine: 15.
Demo fiddle here.
Is it possible?
Your JSON root object consists of certain fixed keys (
"sol_keys"and"validity_checks") whose values each have some fixed schema, and any number of variable keys (the"782"numeric keys) whose values all share a common schema that differs from the schemas of the fixed key values:You would like to deserialize just the variable keys, but when you try to deserialize to a
Dictionary<string, MarsWheather>you get an exception because the serializer tries to deserialize a fixed key value as if it were variable key value -- but since the fixed key has an array value while the variable keys have object values, an exception gets thrown. How canSystem.Text.Jsonbe told to skip the known, fixed keys rather than trying to deserialize them?If you want to deserialize just the variable keys and skip the fixed, known keys, you will need to create a custom
JsonConverter. The easiest way to do that would be to first create some root object for your dictionary:And then define the following converter for it as follows:
And now you will be able to deserialize to
MarsWheatherRootObjectas follows:Demo fiddle #1 here.
Notes:
FixedAndvariablePropertyNameObjectConverter<TObject, TDictionary, TValue>provides a general framework for serializing and deserializing objects with fixed and variable properties. If later you decide to deserialize e.g."sol_keys", you could modifyMarsWheatherRootObjectas follows:And the converter as follows:
Demo fiddle #2 here.