An easier method to deserialize json from NASA InSight: Mars Weather Service API
Published: 2021-05-17 10:17:33

NASA has a free service with Mars wheather. I'm trying to use it and create a pet project with beautiful Mars's photos and wheathers descriptions.
You can see demo data with this [URL](https://api.nasa.gov/insight_weather/?api_key=DEMO_KEY&feedtype=json&ver=1.0) 
Just this time the service doesn't work but I hope It will work soon.
I have saved json for unit tests and show it for clarity:
```
{
    "781": {
        "First_UTC": "2021-02-05T16:28:36Z",
        "Last_UTC": "2021-02-06T17:08:11Z",
        "Month_ordinal": 12,
        "Northern_season": "late winter",
        "PRE": {
            "av": 717.422,
            "ct": 120387,
            "mn": 695.3022,
            "mx": 742.7693
        },
        "Season": "winter",
        "Southern_season": "late summer",
        "WD": {
            "most_common": null
        }
    },
// and so forth, and so on
    "sol_keys": [
        "781"
// and so forth, and so on
    ]
}
```
Some monthes ago I've created a post with one of the methods to deserialize NASA data using custom JsonConverter.
But now I think that there is an more easier method to do it.
Let's begin.
I have a class with description.
```
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; }

        [JsonIgnore]
        public HashSet<string> Photos { get; set; }
        [JsonIgnore]
        public List<RoverInfo> Rovers { 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; }
    }
    public enum RoverName
    {
        Curiosity,
        Opportunity,
        Spirit
    }

    public class RoverInfo {
        public string Name { get; set; }
        public DateTime LandingDate { get; set; }
        public DateTime LaunchDate { get; set; }
        public string Status { get; set; }
    }
```
I've read a [description of service] (https://api.nasa.gov/assets/insight/InSight%20Weather%20API%20Documentation.pdf) not attentively, that was why I've missed this paragraph
> Get a top-level Sol key from the top-level key sol_keys

Ha-ha, it was a big mistake! I should return to my server and change a method to get data.
I've added a new class to process json (CustomDeserializer.cs)
```
public static class CustomDeserializer
    {
        static string fieldName = "sol_keys";
        public static async Task<IEnumerable<MarsWheather>> GetAsync(Stream stream)
        {
            var result = new List<MarsWheather>();
            using (var document = JsonDocument.Parse(stream))
            {
                var root = document.RootElement;
                var keys = root.GetProperty(fieldName);
                foreach (var key in keys.EnumerateArray())
                {
                    if (root.TryGetProperty(key.GetString(), out var element))
                    {
                            var wheather = await JsonSerializer.DeserializeAsync<MarsWheather>(new MemoryStream(Encoding.ASCII.GetBytes(element.GetRawText())));
                            int.TryParse(key.GetString(), out var sol);
                            wheather.Sol = sol;
                            result.Add(wheather);                        
                    }
                }
            }
            return result;
        }
    }
```
And this works!