强制将空JSON数组转换为Dictionary类型 [英] Force conversion of empty JSON array to Dictionary type

查看:86
本文介绍了强制将空JSON数组转换为Dictionary类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是,PHP中的json_encode()函数使正在读取其输出的工具含糊不清.在PHP中,列表和字典都是array的相同类型.

The problem is, that json_encode() function in PHP leaves ambiguity for tools which are reading its output. In PHP both lists and dictionaries are same type of array.

echo json_encode([]); // []
echo json_encode(["5" => "something"]); // {"5": "something"}

在JSON.NET中,我想同时将[]{"5": "something"}都强制转换为Dictionary<string, string>类型.但是,它将[]识别为Dictionary的禁止结构,并引发异常.

In JSON.NET I want to force both [] and {"5": "something"} to convert to Dictionary<string, string> type. However it recognizes [] as prohibited structure for Dictionary and throws an Exception.

我可以快速将空的JSON数组保留为空或强制将其转换为空的字典类型吗?

Can I quickly leave empty JSON arrays nulled or force them to convert to empty Dictionary type?

最终解决方案

我修改了接受的答案,以使其通用且可用于其他类型.

I modified accepted answer to make it generic and reusable for other types.

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();
    }
}

您应将其与JSON对象一起使用,如下例所示:

You should use it with your JSON object as in example below:

public class Company
{
    public string industry_name { get; set; }

    [JsonConverter(typeof(DictionaryOrEmptyArrayConverter<int, Upgrade>))]
    public Dictionary<int, Upgrade> upgrades { get; set; }
}

public class Upgrade
{
    public int level { get; set; }
}

它允许您使用DeserializeObject方法将JSON字符串快速转换为对象:

It allows you to quickly convert JSON string to objects with DeserializeObject method:

var result = JsonConvert.DeserializeObject<Company>(jsonString);

推荐答案

您可以使用自定义的JsonConverter来做到这一点,尽管我认为此解决方案仍有待改进:

You can do it with a custom JsonConverter, although I think this solution leaves a bit to be desired:

    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();
        }
    }

https://dotnetfiddle.net/zzlzH4

这篇关于强制将空JSON数组转换为Dictionary类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆