CustomConverter 无法获取对象的名称

CustomConverter doesn't works to get names of objects

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

和一个 Person class 列表成员:

public class Persons
    {
        [JsonConverter(typeof(JsonObjectsToListConverter))]
        public List<String> listPers { get; set; }
    }

问题是 CustomConverter return null 除非我将父对象添加到 json 中,例如:

{"listP":
    {
    "Bryan":{
....

[JsonProperty("listP")] 人 Class.

我不明白在反序列化过程中发生了什么,以及为什么没有 PropertyName 属性反序列化就不能正常工作。

下面的描述非常简单,但非常接近反序列化的实际过程。

一旦您为 JsonConvert.DeserializeObject 方法提供字符串和目标类型,它就会开始将您指定的类型的结构与字符串的结构进行比较。它查找所提供类型的 public 属性,并在字符串中搜索相同的 属性 事件。它不知道你在字符串中指定的 json 数组应该进入名为 "listP" 的 属性 直到你 link 在 json 和使用名称的类型之间对于 json 数组。

现在,您不必使用 JsonProperty 属性指定 "listP" 属性 名称。 json 数组与 class 属性 具有相同的名称就足够了:"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());