Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法反序列化当前JSON对象(空数组)_C#_Json_Json.net - Fatal编程技术网

C# 无法反序列化当前JSON对象(空数组)

C# 无法反序列化当前JSON对象(空数组),c#,json,json.net,C#,Json,Json.net,我试图制作一个程序,将所有这些对象格式化成一个树状视图,为此(我使用JSON对对象进行排序),我需要解析JSON,所以我选择了JSON.NET 下面是一个格式设置的示例: { “空间”:{ “ClassName”:“SpaceObject”, “名称”:“空间”, “儿童”:{ “对象1”:{ “类名称”:“对象”, “名称”:“Object1”, “儿童”:[] }, “目标2”:{ “类名称”:“对象”, “名称”:“Object2”, “儿童”:[] } } } } 公共类CObject

我试图制作一个程序,将所有这些对象格式化成一个树状视图,为此(我使用JSON对对象进行排序),我需要解析JSON,所以我选择了JSON.NET

下面是一个格式设置的示例:

{
“空间”:{
“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();