【问题标题】:Can I add additional type that will combine multiple json properties when deserializing JSON?在反序列化 JSON 时,我可以添加将组合多个 json 属性的其他类型吗?
【发布时间】:2017-12-08 15:52:18
【问题描述】:

原始的 JSON C# 类结构看起来像

 public class Main
    {
        public double temp { get; set; }
        public double temp_min { get; set; }
        public double temp_max { get; set; }
        public double pressure { get; set; }
        public double sea_level { get; set; }
        public double grnd_level { get; set; }
        public int humidity { get; set; }
        public double temp_kf { get; set; }
    }

    public class Weather
    {
        public int id { get; set; }
        public string main { get; set; }
        public string description { get; set; }
        public string icon { get; set; }
    }

    public class Clouds
    {
        public int all { get; set; }
    }

    public class Wind
    {
        public double speed { get; set; }
        public double deg { get; set; }
    }

    public class Snow
    {
        public double? 3h { get; set; }
    }

    public class Sys
    {
        public string pod { get; set; }
    }

    public class Rain
    {
        public double 3h { get; set; }
    }

    public class List
    {
        public int dt { get; set; }
        public Main main { get; set; }
        public IList<Weather> weather { get; set; }
        public Clouds clouds { get; set; }
        public Wind wind { get; set; }
        public Snow snow { get; set; }
        public Sys sys { get; set; }
        public string dt_txt { get; set; }
        public Rain rain { get; set; }
    }

    public class Coord
    {
        public double lat { get; set; }
        public double lon { get; set; }
    }

    public class City
    {
        public int id { get; set; }
        public string name { get; set; }
        public Coord coord { get; set; }
        public string country { get; set; }
    }

    public class Example
    {
        public string cod { get; set; }
        public double message { get; set; }
        public int cnt { get; set; }
        public IList<List> list { get; set; }
        public City city { get; set; }
    }

我想删除一些属性并将其他属性合并到我的类型中,所以最后我想获得下一个 C# 类结构:

public class WeatherForecast
    {
        [JsonProperty("city")]
        public City City { get; set; }

        [JsonProperty("list")]
        public IList<ClimateIndicators> ClimateIndicators { get; set; }
    }

 public class ClimateIndicators
    {
        public Atmospheric Atmospheric { get; set; }
        public Hydrospheric Hydrospheric { get; set; }
        public Lithospheric Lithospheric { get; set; }
        public DateTime Date { get; set; }

        public IList<WeatherDetails> WeatherDetails { get; set; }
    }

 public class Atmospheric
    {
        [JsonProperty("pressure")]
        public double Pressure { get; set; }
        [JsonProperty("humidity")]
        public int Humidity { get; set; }
        [JsonProperty("sea_level")]
        public double SeaLevel { get; set; }
        [JsonProperty("grnd_level")]
        public double GroundLevel { get; set; }
        [JsonProperty("all")]
        public int Cloudiness { get; set; }
        [JsonProperty("rain")]
        public double? Rain { get; set; }
        [JsonProperty("snow")]
        public double? Snow { get; set; } 
    }

我正在为天气状况添加自定义分类。所以我面临的问题是我不知道如何将多个 JSON 属性合并到一个类中,该类是另一个 JSON 属性的属性。

【问题讨论】:

  • 你的 json 在哪里?
  • 您要反序列化的 JSON 是什么,它与您要实现的新模型之间的映射是什么?此外,您想要的模型缺少一堆类。 HydrosphericLithosphericWeatherDetails的定义是什么?
  • @BrianRogers samples.openweathermap.org/data/2.5/… 忽略这三个。我想将 Clouds Wind Snow 和 Main 结合到 Atmospheric 类中。如何在反序列化时创建 Atmospheric 对象并将这些属性移入其中?

标签: c# json json.net json-deserialization


【解决方案1】:

由于您想要的类结构与 JSON 具有不同的形状,因此您需要创建一个自定义 JsonConverter 来弥合差异。在您的情况下,WeatherForecastCity 类不需要任何特殊处理(仅使用 [JsonProperty] 属性就足够了),但 ClimateIndicators 类肯定需要转换器。

这是它在代码中的样子。转换器通过将list 数组的每个项目的JSON 数据加载到临时JObject 中来工作。 (Json.Net 为每个项目调用一次 ReadJson,所以这就是转换器中没有循环的原因。)从那里,SelectToken 用于从填充实例所需的各种嵌套项目属性中挑选值属于ClimateIndicators 类及其支持类Atmospheric。然后将 ClimateIndicators 实例返回给 Json.Net,Json.Net 会自动将其添加到 WeatherForecast 类的列表中。

class ClimateIndicatorsConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(ClimateIndicators);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject obj = JObject.Load(reader);

        Atmospheric atm = new Atmospheric();
        atm.Pressure = (double)obj.SelectToken("main.pressure");
        atm.Humidity = (int)obj.SelectToken("main.humidity");
        atm.SeaLevel = (double)obj.SelectToken("main.sea_level");
        atm.GroundLevel = (double)obj.SelectToken("main.grnd_level");
        atm.Cloudiness = (int)obj.SelectToken("clouds.all");
        atm.Rain = (double?)obj.SelectToken("rain.3h");
        atm.Snow = (double?)obj.SelectToken("snow.3h");

        ClimateIndicators indicators = new ClimateIndicators();
        indicators.Atmospheric = atm;
        indicators.Date = (DateTime)obj.SelectToken("dt_txt");

        return indicators;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

要使用转换器,请将[JsonConverter] 属性添加到ClimateIndicators 类,如下所示:

    [JsonConverter(typeof(ClimateIndicatorsConverter))]
    public class ClimateIndicators
    {
        ...
    }

请注意,ClimateIndicatorsAtmospheric 类中的属性不需要 [JsonProperty] 属性,因为属性映射正在由转换器处理。

这是一个工作演示:https://dotnetfiddle.net/Fc9G69

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    • 2014-01-24
    • 1970-01-01
    • 2020-02-19
    • 2017-11-15
    相关资源
    最近更新 更多