I want to create home pet project with Mars wheather. Thanks God NASA have a public API with data.
Test URL https://api.nasa.gov/insight_weather/?api_key=DEMO_KEY&feedtype=json&ver=1.0
And there is their json for today :
{
"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
}
}, ... irrelevant
"sol_keys": [... irrelevant],
"validity_checks": { ...irrelevant }
}
I've created a project using netcoreapp3.0 and wanted to use System.Text.Json library. My first wrong way to do it was :
var dict = await JsonSerializer.DeserializeAsync<Dictionary<string, MarsWheather>>(stream);
But I caught an exception
System.Text.Json.JsonException: The JSON value could not be converted to MarsWheather. Path: $.sol_keys | LineNumber: 120 | BytePositionInLine: 15.
BOOM!
That's why I've created custom JsonConverter. I hope this code will helpful for community.
UPDATE 03/03/2021 : There was a bug with my code. This is a new version without it.
Data classes is :
[JsonConverter(typeof(MarsWheatherRootObjectConverter))]
public class MarsWheatherRootObject
{
public List<MarsWheather> MarsWheather { get; set}
}
public class MarsWheather {
public int Sol { get; set; }
[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; }
}
I've created an class wrapper (MarsWheatherRootObject) to use class attribute.
internal class MarsWheatherRootObjectConverter : JsonConverter<MarsWheatherRootObject>
{
public override MarsWheatherRootObject Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var root = new MarsWheatherRootObject();
var list = new List<MarsWheather>();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonTokenType.PropertyName:
case JsonTokenType.String:
var keyStr = reader.GetString();
int key;
if (!int.TryParse(keyStr, out key))
{
reader.Skip();
}
else
{
var value = JsonSerializer.Deserialize<MarsWheather>(ref reader, options);
value.Sol = key;
list.Add(value);
}
break;
default: break;
}
}
root.MarsWheather = list;
return root;
}
public override void Write(Utf8JsonWriter writer, MarsWheatherRootObject value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
I don't need to serialize the object. That's why I don't write code for Write method by now.
Top comments (0)