代码之家  ›  专栏  ›  技术社区  ›  Lex Webb

JSON。Net无法在自定义JsonConverter中反序列化json数组

  •  2
  • Lex Webb  · 技术社区  · 8 年前

    我遇到了一个我似乎无法解决的令人困惑的问题。

    我使用的是Json。Net编写了一个自定义Json转换器来处理我的应用程序中的特殊情况。 我遇到的问题是反序列化或 ReadJson 方法,该方法在尝试将JSON数组转换为字符串数组时引发错误:

    enter image description here

    错误的确切文本为: Unexpected token while deserializing object: PropertyName. Path 'RootPages', line 1, position 13.

    正如您从检查器中看到的,它试图反序列化的JProperty(RootPages)已被正确解析,并且是有效的JSON。 enter image description here

    所以我不完全确定这里发生了什么,任何启示都将不胜感激。。

    如果相关,原始JSON字符串如下所示:

    {
      "RootPages": [
        "TestItem1",
        "TestItem2"
      ],
      "Name": "root"
    }
    

    编辑代码:

    ReadJson方法:

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
            if (PartialChildPageSerialization) {
                var jsonObject = JObject.Load(reader);
                var properties = jsonObject.Properties().ToList();
    
                foreach (var property in objectType.GetProperties()) {
                    var type = property.PropertyType;
                    object value = null;
    
                    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ChildPageCollection<>)) {
                        var collection = Activator.CreateInstance(type);
                        var deserializedValue = properties.First(p => p.Name == property.Name).ToObject<string[]>();
                        type.GetMethod("PolulateFromSerializer").Invoke(collection, new object[] {deserializedValue});
                        value = collection;
                    }
                    else {
                        value = properties.First(p => p.Name == property.Name).ToObject(type);
                    }
    
                    property.SetValue(existingValue, value);
                }
    
                return existingValue;
            }
    
            return serializer.Deserialize(reader, objectType);
        }
    

    ChildPageCollection有趣部分的片段:

    public class ChildPageCollection<T> : IList<T> where T : DataPage
    {
        public string[] GetNames() => _internalNameList.ToArray();
    
        internal void PolulateFromSerializer(string[] names) {
            this.Clear();
            _internalNameList.AddRange(names);
            _hasFullList = false;
        }
    
        private void CheckFullList() {
            if(!_hasFullList)
                throw new InvalidOperationException("Collection has not been fully loaded, and full list is not avialable.");
        }
    
        private readonly List<T> _internalList = new List<T>();
        private readonly List<string> _internalNameList = new List<string>();
        private bool _hasFullList = true;
    
        ...
    }
    
    1 回复  |  直到 8 年前
        1
  •  3
  •   Mark Rawson    8 年前

    我认为这是因为第一个属性是一个对象,其属性名为“RootPages”,它是一个字符串[]。

    不幸的是,从屏幕截图的外观来看,您正试图将对象转换为字符串数组。

    这应该在您给出的示例中起作用:

    properties.First(p => p.Name == property.Name).Select(o => o.Children().Values<string>()).First().ToArray();
    

    代替:

    properties.First(p => p.Name == property.Name).ToObject<string[]>();
    
    推荐文章