任何人都可以告诉我在尝试反序列化此Zoho Docs API响应时我做错了吗?
我的文件夹结构为"我的文件夹"作为根然后" TestFolder"在里面。这是我从Zoho Docs API返回的JSON响应:
[
{
"FOLDER_NAME": "My Folders",
"SUCCESS": "1",
"SCOPE": "0"
},
[
{
"AUTHOR_ID": "123456",
"FOLDER_ID": "xxx",
"PARENT_FOLDER_ID": "1",
"FOLDER_NAME": "TestFolder",
"LAST_MODIFIED_TIME": "1435875889219",
"ENCFOLDER_NAME": "TestFolder",
"SCOPE": "0",
"AUTHOR_NAME": "John Smith",
"LAST_MODIFIEDBY": "123456",
"IS_SHARED": true,
"LAST_MODIFIED_AUTHOR_NAME": "John Smith"
}
]
]
我已经尝试使用此课程将响应反序列化为文件夹或列表,但我没有运气:
public class Folder
{
[JsonProperty("FOLDER_NAME")]
public string FolderName { get; set; }
}
我是否尝试将其反序列化为对象或文件夹列表我从Json.NET得到此错误:
无法将当前的JSON数组(例如[1,2,3])反序列化为类型' ZohoModels.Folder'因为该类型需要一个JSON对象(例如{" name":" value"})才能正确反序列化。
要修复此错误,请将JSON更改为JSON对象(例如{" name":" value"})或将反序列化类型更改为数组或实现的类型像List这样的集合接口(例如ICollection,IList)可以从JSON数组反序列化。 JsonArrayAttribute也可以添加到类型中,以强制它从JSON数组反序列化。
答案 0 :(得分:1)
这里有两个问题:
根容器是一个数组而不是一个对象,因此需要反序列化为一个集合,比如List<Folder>
。
该数组包含两个条目:JSON对象和嵌套的JSON数组。 documentation是模糊的,但看起来这些文件夹是递归的,并且文件夹数组将包含成对的文件夹/子文件夹数组容器。由于Json.NET决定是否根据它是否实现IEnumerable
来序列化POCO,因此没有单个类可以从JSON数组和JSON对象反序列化。因此,有必要为List<Folder>
创建一个自定义JSON转换器,以跳过数组并将文件夹与其子阵列进行匹配。
以下类和转换器应该完成这项工作:
public class Folder
{
public Folder() { this.Folders = new List<Folder>(); }
[JsonProperty("FOLDER_NAME")]
public string FolderName { get; set; }
public List<Folder> Folders { get; set; }
}
public class FolderListConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(List<Folder>);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
// Format of a folder list is
// Object with name of folder
// Array of child folders as a folderlist.
var folders = (existingValue as List<Folder> ?? new List<Folder>());
var array = JArray.Load(reader);
foreach (var token in array)
{
switch (token.Type)
{
case JTokenType.Object:
folders.Add(token.ToObject<Folder>(serializer));
break;
case JTokenType.Array:
{
var folder = folders.Last(); // Throws an exception if none read yet.
(folder.Folders = (folder.Folders ?? new List<Folder>())).AddRange(token.ToObject<List<Folder>>(serializer));
}
break;
default:
throw new JsonSerializationException("unknown token " + token.ToString());
}
}
return folders;
}
public override bool CanWrite { get { return false; }}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
并使用它:
var settings = new JsonSerializerSettings { Converters = new JsonConverter[] { new FolderListConverter() } };
var folders = JsonConvert.DeserializeObject<List<Folder>>(json, settings);