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,问题是,PHP中的json_encode()函数会给读取其输出的工具留下歧义。在PHP中,列表和字典都是相同类型的数组 echo json_encode([]); // [] echo json_encode(["5" => "something"]); // {"5": "something"} 在JSON.NET中,我想强制[]和{“5”:“something”}转换为字典类型。但是,它将[]识别为字典的禁止结构,并引发异常 我是否可以快速地将空JSON数组保留为null或强制它们转

问题是,PHP中的
json_encode()
函数会给读取其输出的工具留下歧义。在PHP中,列表和字典都是相同类型的
数组

echo json_encode([]); // []
echo json_encode(["5" => "something"]); // {"5": "something"}
在JSON.NET中,我想强制
[]
{“5”:“something”}
转换为
字典
类型。但是,它将
[]
识别为字典的禁止结构,并引发异常

我是否可以快速地将空JSON数组保留为null或强制它们转换为空字典类型

最终解决方案

我修改了accepted answer,使其具有通用性,并可用于其他类型

public class DictionaryOrEmptyArrayConverter<T,F> : JsonConverter
{
    public override bool CanWrite { get { return false; } }
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Dictionary<T, F>);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        switch (reader.TokenType)
        {
            case JsonToken.StartArray:
                reader.Read();
                if (reader.TokenType == JsonToken.EndArray)
                    return new Dictionary<T, F>();
                else
                    throw new JsonSerializationException("Non-empty JSON array does not make a valid Dictionary!");
            case JsonToken.Null:
                return null;
            case JsonToken.StartObject:
                var tw = new System.IO.StringWriter();
                var writer = new JsonTextWriter(tw);
                writer.WriteStartObject();
                int initialDepth = reader.Depth;
                while (reader.Read() && reader.Depth > initialDepth)
                {
                    writer.WriteToken(reader);
                }
                writer.WriteEndObject();
                writer.Flush();
                return JsonConvert.DeserializeObject<Dictionary<T, F>>(tw.ToString());
            default:
                throw new JsonSerializationException("Unexpected token!");
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

您可以使用自定义的
JsonConverter
来实现这一点,尽管我认为这个解决方案还有一些不足之处:

    private class DictionaryConverter : JsonConverter
    {
        public override bool CanWrite { get { return false; } }
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Dictionary<string, string>);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.StartArray)
            {
                reader.Read();
                if (reader.TokenType == JsonToken.EndArray)
                    return new Dictionary<string, string>();
                else
                    throw new JsonSerializationException("Non-empty JSON array does not make a valid Dictionary!");
            }
            else if (reader.TokenType == JsonToken.Null)
            {
                return null;
            }
            else if (reader.TokenType == JsonToken.StartObject)
            {
                Dictionary<string, string> ret = new Dictionary<string, string>();
                reader.Read();
                while (reader.TokenType != JsonToken.EndObject)
                {
                    if (reader.TokenType != JsonToken.PropertyName)
                        throw new JsonSerializationException("Unexpected token!");
                    string key = (string)reader.Value;
                    reader.Read();
                    if (reader.TokenType != JsonToken.String)
                        throw new JsonSerializationException("Unexpected token!");
                    string value = (string)reader.Value;
                    ret.Add(key, value);
                    reader.Read();
                }
                return ret;
            }
            else
            {
                throw new JsonSerializationException("Unexpected token!");
            }
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
私有类字典转换程序:JsonConverter
{
公共重写bool可以写入{get{return false;}}
公共覆盖布尔CanConvert(类型objectType)
{
返回objectType==typeof(字典);
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
if(reader.TokenType==JsonToken.StartArray)
{
reader.Read();
if(reader.TokenType==JsonToken.EndArray)
返回新字典();
其他的
抛出新的JsonSerializationException(“非空JSON数组不构成有效字典!”);
}
else if(reader.TokenType==JsonToken.Null)
{
返回null;
}
else if(reader.TokenType==JsonToken.StartObject)
{
字典ret=新字典();
reader.Read();
while(reader.TokenType!=JsonToken.EndObject)
{
if(reader.TokenType!=JsonToken.PropertyName)
抛出新的JsonSerializationException(“意外标记!”);
字符串键=(字符串)reader.Value;
reader.Read();
if(reader.TokenType!=JsonToken.String)
抛出新的JsonSerializationException(“意外标记!”);
字符串值=(字符串)reader.value;
ret.Add(键、值);
reader.Read();
}
返回ret;
}
其他的
{
抛出新的JsonSerializationException(“意外标记!”);
}
}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
抛出新的NotImplementedException();
}
}

请在

中查看此代码,或者您可以通过删除所有这些空数组属性来预处理json文本

//Will not work with formatted json due to whitespace    
json = Regex.Replace(json, ",?\"[^\"]+\":[[]]", "");
    private class DictionaryConverter : JsonConverter
    {
        public override bool CanWrite { get { return false; } }
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Dictionary<string, string>);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.StartArray)
            {
                reader.Read();
                if (reader.TokenType == JsonToken.EndArray)
                    return new Dictionary<string, string>();
                else
                    throw new JsonSerializationException("Non-empty JSON array does not make a valid Dictionary!");
            }
            else if (reader.TokenType == JsonToken.Null)
            {
                return null;
            }
            else if (reader.TokenType == JsonToken.StartObject)
            {
                Dictionary<string, string> ret = new Dictionary<string, string>();
                reader.Read();
                while (reader.TokenType != JsonToken.EndObject)
                {
                    if (reader.TokenType != JsonToken.PropertyName)
                        throw new JsonSerializationException("Unexpected token!");
                    string key = (string)reader.Value;
                    reader.Read();
                    if (reader.TokenType != JsonToken.String)
                        throw new JsonSerializationException("Unexpected token!");
                    string value = (string)reader.Value;
                    ret.Add(key, value);
                    reader.Read();
                }
                return ret;
            }
            else
            {
                throw new JsonSerializationException("Unexpected token!");
            }
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
//Will not work with formatted json due to whitespace    
json = Regex.Replace(json, ",?\"[^\"]+\":[[]]", "");