我收到这样一个json:
{
"Bryan": {
"age": 25,
"city": "Miami"
},
"Jeff": {
"age": 24,
"city": "Tokyo"
}
}
我想要反序列化以获得list<String>
中人员的名称。这里有一个CustomJsonConverter
:
public class JsonObjectsToListConverter : JsonConverter
{
public JsonObjectsToListConverter()
{
}
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(HashSet<String>));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jtoken = JToken.Load(reader);
JObject jObjectCast = jtoken.Value<JObject>();
List<String> listPers = (from prop in jObjectCast.Properties()
select prop.Name).ToList();
return listPers;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
和具有List成员的Person类:
public class Persons
{
[JsonConverter(typeof(JsonObjectsToListConverter))]
public List<String> listPers { get; set; }
}
问题在于CustomConverter返回null,除非我将父对象添加到json中,如:
{"listP":
{
"Bryan":{
....
和Persons Class中的[JsonProperty("listP")]
。
我不明白反序列化过程中发生了什么,为什么没有PropertyName
属性就不能正常工作。
下面的描述非常简化,但非常接近反序列化的实际过程。
一旦您为JsonConvert.DeserializeObject
方法提供了字符串和目标类型,它就开始比较您指定的类型的结构与字符串的结构。它查找所提供类型的公共属性,并在字符串中搜索相同的属性。它不知道你在string中指定的json数组应该进入名为"listP"的属性,直到你在json和json数组的类型使用名称之间建立链接。
JsonProperty
属性指定"listP"属性名。只需使用与类属性同名的json数组即可:"listPers"。
如果你想简化反序列化的过程,但是,没有额外的开销在json本身和不必要的属性装饰,它会更容易编写类似于下面的代码:
public class Persons
{
public List<String> ListPers { get; set; }
}
public class JsonObjectsToPersonsConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Persons));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Persons value = new Persons();
JToken jtoken = JToken.Load(reader);
JObject jObjectCast = jtoken.Value<JObject>();
List<String> listPers = (from prop in jObjectCast.Properties()
select prop.Name).ToList();
return new Persons { ListPers = listPers};
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
并像这样反序列化数据:
var persons = JsonConvert.DeserializeObject<Persons>(
@"{
'Bryan': {
'age': 25,
'city': 'Miami'
},
'Jeff': {
'age': 24,
'city': 'Tokyo'
}
}",
new JsonObjectsToPersonsConverter());