C# 无法反序列化当前JSON对象(空数组)
我试图制作一个程序,将所有这些对象格式化成一个树状视图,为此(我使用JSON对对象进行排序),我需要解析JSON,所以我选择了JSON.NET 下面是一个格式设置的示例:C# 无法反序列化当前JSON对象(空数组),c#,json,json.net,C#,Json,Json.net,我试图制作一个程序,将所有这些对象格式化成一个树状视图,为此(我使用JSON对对象进行排序),我需要解析JSON,所以我选择了JSON.NET 下面是一个格式设置的示例: { “空间”:{ “ClassName”:“SpaceObject”, “名称”:“空间”, “儿童”:{ “对象1”:{ “类名称”:“对象”, “名称”:“Object1”, “儿童”:[] }, “目标2”:{ “类名称”:“对象”, “名称”:“Object2”, “儿童”:[] } } } } 公共类CObject
{
“空间”:{
“ClassName”:“SpaceObject”,
“名称”:“空间”,
“儿童”:{
“对象1”:{
“类名称”:“对象”,
“名称”:“Object1”,
“儿童”:[]
},
“目标2”:{
“类名称”:“对象”,
“名称”:“Object2”,
“儿童”:[]
}
}
}
}
公共类CObject
{
[JsonProperty(PropertyName=“Name”)]
公共字符串名称{get;set;}
[JsonProperty(PropertyName=“ClassName”)]
公共字符串类名{get;set;}
[JsonProperty(PropertyName=“Children”)]
公共IDictionary子项{get;set;}
}
IDictionary obj=JsonConvert.DeserializeObject(Json,新的JsonSerializerSettings(){
MissingMemberHandling=MissingMemberHandling.Ignore,
NullValueHandling=NullValueHandling.Ignore,
});
foreach(obj中的var i){
ExplorerView1.Nodes.Add(AddObject(i.Value));
}
我相信我发现了错误,这是由于子数组中没有对象。我不知道如何解决这个问题,有人能帮忙吗?
JsonSingleOrEmptyArrayConverter
从到几乎可以满足您的需要。只需对其进行增强,以允许当前契约类型既是字典契约又是对象契约
首先,修改JsonSingleOrEmptyArrayConverter
,如下所示:
public class JsonSingleOrEmptyArrayConverter<T> : JsonConverter where T : class
{
//https://stackoverflow.com/questions/29449641/deserialize-json-when-type-can-be-different?rq=1
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override bool CanWrite { get { return false; } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var contract = serializer.ContractResolver.ResolveContract(objectType);
// Allow for dictionary contracts as well as objects contracts, since both are represented by
// an unordered set of name/value pairs that begins with { (left brace) and ends with } (right brace).
if (!(contract is Newtonsoft.Json.Serialization.JsonObjectContract
|| contract is Newtonsoft.Json.Serialization.JsonDictionaryContract))
{
throw new JsonSerializationException(string.Format("Unsupported objectType {0} at {1}.", objectType, reader.Path));
}
switch (reader.SkipComments().TokenType)
{
case JsonToken.StartArray:
{
int count = 0;
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.Comment:
break;
case JsonToken.EndArray:
// You might want to allocate an empty object here if existingValue is null
// If so, do
// return existingValue ?? contract.DefaultCreator();
return existingValue;
default:
{
count++;
if (count > 1)
throw new JsonSerializationException(string.Format("Too many objects at path {0}.", reader.Path));
existingValue = existingValue ?? contract.DefaultCreator();
serializer.Populate(reader, existingValue);
}
break;
}
}
// Should not come here.
throw new JsonSerializationException(string.Format("Unclosed array at path {0}.", reader.Path));
}
case JsonToken.Null:
return null;
case JsonToken.StartObject:
existingValue = existingValue ?? contract.DefaultCreator();
serializer.Populate(reader, existingValue);
return existingValue;
default:
throw new InvalidOperationException("Unexpected token type " + reader.TokenType.ToString());
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public static partial class JsonExtensions
{
public static JsonReader SkipComments(this JsonReader reader)
{
while (reader.TokenType == JsonToken.Comment && reader.Read())
;
return reader;
}
}
var settings = new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore,
Converters = { new JsonSingleOrEmptyArrayConverter<IDictionary<string, CObject>>() },
};
var obj = JsonConvert.DeserializeObject<IDictionary<string, CObject>>(Json, settings);
正在使用.Net fiddle。您的JSON无效--第10行有一个解析错误--在
}
和“Object2”
之间应该有一个逗号。我可以假设这是一个输入错误吗?您的json结构和Cobject定义不匹配。在json中,子对象是一个数组,但在Cobject类定义中,它是一个字典。
// You might want to allocate an empty object here if existingValue is null
// If so, do
// return existingValue ?? contract.DefaultCreator();