【问题标题】:Can I deserialize a JSON array into properties of a class?我可以将 JSON 数组反序列化为类的属性吗?
【发布时间】:2020-05-01 18:25:46
【问题描述】:

我有一个包含如下行的 JSON 文件:

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

coordinates 项目是城市的地理坐标。但是它被存储为一个数组,该数组总是包含 [longitude, latitude]。

我想将这些条目反序列化为这样定义的 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 可以正确反序列化为我想要的对象图?

我目前正在使用System.Text.Json,但如果有更好的解决方案,我会立即切换到Newtonsoft.Json

澄清

我知道如何将 JSON 反序列化为一个类,其中 JSON 元素和类属性之间存在对应关系。这里的基本问题是源 JSON 文件包含一个 2 元素数组,我想在我的反序列化类的属性中结束,而不是在单个数组属性中。我不知道如何做到这一点。

【问题讨论】:

  • @RufusL 不是真的,因为他们都没有解决我的问题。我知道如何反序列化为所有 JSON 属性都与类属性匹配的类,但我不知道如何将 JSON 数组反序列化为类的属性。
  • 可以写自定义JsonConverter
  • 如果没有简单的方法来做到这一点,我很想只使用编辑器对输入文件进行搜索和替换,这是一个永远不会发生的静态文件改变。
  • Newtonsoft 有一个 Custom JsonConverterr<T> 的想法,它允许您实现一个将该数组转换为新的 GeographicLocation 实例的类。

标签: c# json deserialization json-deserialization system.text.json


【解决方案1】:

如上所述,您可以使用自定义 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);

【讨论】:

  • 太棒了,谢谢。您应该因为提供这样有用且完整的答案而获得更高的声誉。这应该会让你有点兴奋:) [41 -> 66]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 2018-06-21
相关资源
最近更新 更多