我可以在 class 和 JSON.Net 上将具有不同名称的 JSON 属性 读入特定的 属性 吗?
Can I read a JSON property with varying names into a specific property on my class with JSON.Net?
我有一个恼人的难题,我有多个类型从 API 返回,它们之间的唯一区别是 属性 名称。一种类型的整数为 Count
,另一种类型的整数为 Customers
,另一种类型的整数为 Replies
.
类 示例:
public class DateAndCount
{
public DateTime? Date { get; set; }
public int Count { get; set; }
}
public class DateAndCount
{
public DateTime? Date { get; set; }
public int Customers { get; set; }
}
public class DateAndCount
{
public DateTime? Date { get; set; }
public int Replies { get; set; }
}
JSON 示例:
{
"count": 40,
"date": "2014-01-01T00:00:00Z"
},
{
"customers": 40,
"date": "2014-01-01T00:00:00Z"
},
{
"replies": 40,
"date": "2014-01-01T00:00:00Z"
},
不必创建 3 个以上几乎完全相同的 类,我能否以某种方式让序列化程序将任何 属性 名称反序列化为 Count
属性?
你可以做一个简单的 JsonConverter
来处理这个问题:
class DateAndCountConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(DateAndCount));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
DateAndCount dac = new DateAndCount();
dac.Date = (DateTime?)jo["Date"];
// put the value of the first integer property from the JSON into Count
dac.Count = (int)jo.Properties().First(p => p.Value.Type == JTokenType.Integer).Value;
return dac;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
要使用它,请使用 [JsonConverter]
属性修饰您的 DateAndCount
class 以将转换器绑定到您的 class,然后照常反序列化。这是一个演示:
class Program
{
static void Main(string[] args)
{
ParseAndDump(@"{ ""Date"" : ""2015-08-22T19:02:42Z"", ""Count"" : 40 }");
ParseAndDump(@"{ ""Date"" : ""2015-08-20T15:55:04Z"", ""Customers"" : 26 }");
ParseAndDump(@"{ ""Date"" : ""2015-08-21T10:17:31Z"", ""Replies"" : 35 }");
}
private static void ParseAndDump(string json)
{
DateAndCount dac = JsonConvert.DeserializeObject<DateAndCount>(json);
Console.WriteLine("Date: " + dac.Date);
Console.WriteLine("Count: " + dac.Count);
Console.WriteLine();
}
}
[JsonConverter(typeof(DateAndCountConverter))]
class DateAndCount
{
public DateTime? Date { get; set; }
public int Count { get; set; }
}
输出:
Date: 8/22/2015 7:02:42 PM
Count: 40
Date: 8/20/2015 3:55:04 PM
Count: 26
Date: 8/21/2015 10:17:31 AM
Count: 35
我有一个恼人的难题,我有多个类型从 API 返回,它们之间的唯一区别是 属性 名称。一种类型的整数为 Count
,另一种类型的整数为 Customers
,另一种类型的整数为 Replies
.
类 示例:
public class DateAndCount
{
public DateTime? Date { get; set; }
public int Count { get; set; }
}
public class DateAndCount
{
public DateTime? Date { get; set; }
public int Customers { get; set; }
}
public class DateAndCount
{
public DateTime? Date { get; set; }
public int Replies { get; set; }
}
JSON 示例:
{
"count": 40,
"date": "2014-01-01T00:00:00Z"
},
{
"customers": 40,
"date": "2014-01-01T00:00:00Z"
},
{
"replies": 40,
"date": "2014-01-01T00:00:00Z"
},
不必创建 3 个以上几乎完全相同的 类,我能否以某种方式让序列化程序将任何 属性 名称反序列化为 Count
属性?
你可以做一个简单的 JsonConverter
来处理这个问题:
class DateAndCountConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(DateAndCount));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
DateAndCount dac = new DateAndCount();
dac.Date = (DateTime?)jo["Date"];
// put the value of the first integer property from the JSON into Count
dac.Count = (int)jo.Properties().First(p => p.Value.Type == JTokenType.Integer).Value;
return dac;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
要使用它,请使用 [JsonConverter]
属性修饰您的 DateAndCount
class 以将转换器绑定到您的 class,然后照常反序列化。这是一个演示:
class Program
{
static void Main(string[] args)
{
ParseAndDump(@"{ ""Date"" : ""2015-08-22T19:02:42Z"", ""Count"" : 40 }");
ParseAndDump(@"{ ""Date"" : ""2015-08-20T15:55:04Z"", ""Customers"" : 26 }");
ParseAndDump(@"{ ""Date"" : ""2015-08-21T10:17:31Z"", ""Replies"" : 35 }");
}
private static void ParseAndDump(string json)
{
DateAndCount dac = JsonConvert.DeserializeObject<DateAndCount>(json);
Console.WriteLine("Date: " + dac.Date);
Console.WriteLine("Count: " + dac.Count);
Console.WriteLine();
}
}
[JsonConverter(typeof(DateAndCountConverter))]
class DateAndCount
{
public DateTime? Date { get; set; }
public int Count { get; set; }
}
输出:
Date: 8/22/2015 7:02:42 PM
Count: 40
Date: 8/20/2015 3:55:04 PM
Count: 26
Date: 8/21/2015 10:17:31 AM
Count: 35