我可以在反序列化 JSON 时添加将组合多个 json 属性的附加类型吗?

Can I add additional type that will combine multiple json properties when deserializing JSON?

原来的JSONC#class结构看起来像

 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# class 结构:

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; } 
    }

我正在为天气状况添加自定义 class化。所以我面临的问题是我不知道如何将多个 JSON 属性合并到一个 class 中,它是另一个 JSON [=26= 的 属性 ].

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

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

中的列表中
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 class,如下所示:

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

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

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