Могу ли я десериализовать массив JSON в свойства класса? - PullRequest
0 голосов
/ 01 мая 2020

У меня есть файл JSON, содержащий такие строки:

{"id":"0258","name":"Canterbury","coordinates":[1.07992,51.27904]}

Элемент coordinates - это географические c координаты города. Однако он хранится в виде массива, который всегда содержит [долготу, широту].

Я хочу десериализовать эти записи в C# POCO-классы, которые определены следующим образом:

    public sealed class City
        {
        [JsonPropertyName("name")]
        public string Name { get; set; }

        [JsonPropertyName("coordinates")]
        public GeographicLocation Location { get; set; }
        }

    public sealed class GeographicLocation
        {
        public GeographicLocation(double latitude, double longitude)
            {
            Latitude = latitude;
            Longitude = longitude;
            }

        public double Latitude { get; private set; }
        public double Longitude { get; private set; }
        }

Я думаю, вы можете видеть, куда я иду с этим.

Есть ли способ аннотировать эти классы так, чтобы источник JSON правильно десериализовался в мой желаемый граф объектов?

I В настоящее время я использую System.Text.Json, но переключился бы на Newtonsoft.Json в одно мгновение, если у него есть лучшее решение.

Уточнение

Я знаю, как десериализовать JSON в класс, где есть соответствие между JSON элементами и свойствами класса. Здесь основная проблема заключается в том, что исходный файл JSON содержит 2-элементный массив, который я хотел бы получить в свойствах моего десериализованного класса, а не в одном свойстве массива. Я не знаю, как это сделать sh.

1 Ответ

2 голосов
/ 01 мая 2020

Как упоминалось выше, вы можете использовать пользовательский JsonConverter <>. Простое решение будет выглядеть так:

public class GeographicLocationJsonConverter : JsonConverter<GeographicLocation>
    {
        public override GeographicLocation ReadJson(JsonReader reader, Type objectType, [AllowNull] GeographicLocation existingValue, bool hasExistingValue, Newtonsoft.Json.JsonSerializer serializer)
        {
            var token = JArray.Load(reader);
            var values = token.ToObject<List<double>>();
            return new GeographicLocation(values[0], values[1]);
        }

        public override void WriteJson(JsonWriter writer, [AllowNull] GeographicLocation value, Newtonsoft.Json.JsonSerializer serializer)
        {
            var jArray = new JArray(new double[] { value.Latitude, value.Longitude });
            jArray.WriteTo(writer);
        }
    }

Использование:

        var city = new City()
        {
            Location = new GeographicLocation(1, 2),
            Name = "Zhytomyr"
        };

        var converter = new GeographicLocationJsonConverter();

        var json = JsonConvert.SerializeObject(city, converter);

        var deserializedCity = JsonConvert.DeserializeObject<City>(json, converter);
...