我可以在反序列化 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
来弥合差异。在您的情况下,WeatherForecast
和 City
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
{
...
}
请注意,ClimateIndicators
或 Atmospheric
class 中的属性不需要 [JsonProperty]
属性,因为正在处理 属性 映射由转换器。
这是一个工作演示:https://dotnetfiddle.net/Fc9G69
原来的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
来弥合差异。在您的情况下,WeatherForecast
和 City
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
{
...
}
请注意,ClimateIndicators
或 Atmospheric
class 中的属性不需要 [JsonProperty]
属性,因为正在处理 属性 映射由转换器。
这是一个工作演示:https://dotnetfiddle.net/Fc9G69