C# 我是否可以添加在反序列化json时将多个json属性组合在一起的其他类型?
原始JSON C#类结构如下所示C# 我是否可以添加在反序列化json时将多个json属性组合在一起的其他类型?,c#,json,json.net,json-deserialization,C#,Json,Json.net,Json Deserialization,原始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
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; }
}
公共类主
{
公共双临时{get;set;}
公共双临时值{get;set;}
公共双临时最大值{get;set;}
公共双重压力{get;set;}
公共双海平面{get;set;}
公共双grnd_级别{get;set;}
公共属性{get;set;}
公共双临时kf{get;set;}
}
公共天气
{
公共int id{get;set;}
公共字符串main{get;set;}
公共字符串说明{get;set;}
公共字符串图标{get;set;}
}
公共类云
{
公共int all{get;set;}
}
公共级风
{
公共双速{get;set;}
公共双deg{get;set;}
}
公共类雪
{
公共双3h{get;set;}
}
公共类系统
{
公共字符串pod{get;set;}
}
公共课雨
{
公共双3h{get;set;}
}
公共班级名单
{
公共int dt{get;set;}
公共Main{get;set;}
公共IList天气{get;set;}
公共云{get;set;}
公共风{get;set;}
公共雪地{get;set;}
公共系统系统{get;set;}
公共字符串dt_txt{get;set;}
公共雨{get;set;}
}
公共类合作社
{
公共双lat{get;set;}
公共双lon{get;set;}
}
公营城市
{
公共int id{get;set;}
公共字符串名称{get;set;}
公共坐标{get;set;}
公共字符串国家{get;set;}
}
公开课范例
{
公共字符串cod{get;set;}
公共双消息{get;set;}
公共int cnt{get;set;}
公共IList列表{get;set;}
公共城市城市{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; }
}
公共类天气预报
{
[JsonProperty(“城市”)]
公共城市城市{get;set;}
[JsonProperty(“列表”)]
公共IList气候指示器{get;set;}
}
公共类气候指示器
{
公共大气{get;set;}
公共水圈水圈{get;set;}
公共岩石圈岩石圈{get;set;}
公共日期时间日期{get;set;}
公共IList WeatherDetails{get;set;}
}
公共级大气
{
[JsonProperty(“压力”)]
公共双重压力{get;set;}
[JsonProperty(“湿度”)]
公共属性{get;set;}
[JsonProperty(“海平面”)]
公共双海平面{get;set;}
[JsonProperty(“grnd_级别”)]
公共双底层{get;set;}
[JsonProperty(“全部”)]
公共int云{get;set;}
[JsonProperty(“rain”)]
公共双?Rain{get;set;}
[JsonProperty(“snow”)]
公共双人雪{get;set;}
}
我正在为天气条件添加自定义分类。因此,我面临的问题是,我不知道如何将多个JSON属性合并到一个属于另一个JSON属性的类中。由于所需的类结构与JSON具有不同的形状,因此需要创建一个自定义的
JsonConverter
来弥合这些差异。在您的例子中,WeatherForecast
和City
类不需要任何特殊处理(仅使用[JsonProperty]
属性就足够了),但是气候指示器
类肯定需要一个转换器
下面是它在代码中的样子。转换器的工作原理是将列表
数组中每个项目的JSON数据加载到一个临时作业对象
。(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]
属性,如下所示:
[JsonConverter(typeof(ClimateIndicatorsConverter))]
public class ClimateIndicators
{
...
}
请注意,ClimateIndicators
或Atmospheric
类中的属性不需要[JsonProperty]
属性,因为属性映射由转换器处理
这是一个有效的演示:因为您想要的类结构与JSON的形状不同,所以您需要创建一个自定义的JsonConverter
来消除这些差异。在您的例子中,WeatherForecast
和City
类不需要任何特殊处理(仅使用[JsonProperty]
属性就足够了),但是气候指示器
类肯定需要一个转换器
下面是它在代码中的样子。转换器的工作原理是将列表
数组中每个项目的JSON数据加载到一个临时作业对象
。(Json.Net为每个项调用一次ReadJson
,因此转换器中没有循环。)从中,SelectToken
用于从填充ClimateIndicators
类及其支持类Atmospheric
实例所需的各种嵌套项属性中选择值。ClimateIndicat