自定义转换器无法获取对象的名称



我收到这样一个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());

相关内容

  • 没有找到相关文章

最新更新