json.net:指定字典键转换器 [英] json.net: specify converter for dictionary keys

查看:84
本文介绍了json.net:指定字典键转换器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JSON:

{ 
    "data": { "A": 5, "B": 6 }, 
    "foo": "foo", 
    "bar": "bar" 
}

我需要将数据反序列化到一个类:

I need to deserialize data into a class:

public Dictionary<MyEnum, int> Data { get; set; }
public string Foo { get; set; }
public string Bar { get; set; }

但MyEnum值 codeA $ C $的cB 而不是简单地 A B 分别。

But MyEnum values are CodeA, and CodeB instead of simply A and B respectively.

我有一个自定义转换器,可以处理的转换。但我怎么指定 JsonConverter 与字典键使用?

I have a custom Converter that can handle conversion. But how do I specify a JsonConverter to use with Dictionary keys?

推荐答案

我认为唯一的办法是使JsonConverter整个词典&LT; MyEnum,INT&GT; 键入或词典&LT; MyEnum,T&GT;

I believe the only way is to make a JsonConverter for the whole Dictionary<MyEnum, int> type, or Dictionary<MyEnum, T>.

字典键不被视为值,并且不会通过JsonConverters运行。类型转换器将是一个解决方案,但默认字符串枚举的转换将进入它着眼于类型转换器之前。

Dictionary keys are not regarded as values and will not be run through the JsonConverters. TypeConverters would have been a solution, but the default string to enum conversion will enter before it looks at the TypeConverters.

所以...我不认为这是可以做到任何其他方式。

So... I don't think it can be done any other way.

编辑:

没有完全测试,但我用这样的事情在我的一个项目:

Not fully tested, but I use something like this in a project of mine:

public class DictionaryWithSpecialEnumKeyConverter : JsonConverter
{
    public override bool CanWrite
    {
        get { return false; }
    }

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;

        var valueType = objectType.GetGenericArguments()[1];
        var intermediateDictionaryType = typeof(Dictionary<,>).MakeGenericType(typeof(string), valueType);
        var intermediateDictionary = (IDictionary)Activator.CreateInstance(intermediateDictionaryType);
        serializer.Populate(reader, intermediateDictionary);

        var finalDictionary = (IDictionary)Activator.CreateInstance(objectType);
        foreach (DictionaryEntry pair in intermediateDictionary)
            finalDictionary.Add(Enum.Parse(MyEnum, "Code" + pair.Key, false), pair.Value);

        return finalDictionary;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType.IsA(typeof(IDictionary<,>)) &&
               objectType.GetGenericArguments()[0].IsA<MyEnum>();
    }
}

您将需要这个小帮手:

    public static bool IsA(this Type type, Type typeToBe)
    {
        if (!typeToBe.IsGenericTypeDefinition)
            return typeToBe.IsAssignableFrom(type);

        var toCheckTypes = new List<Type> { type };
        if (typeToBe.IsInterface)
            toCheckTypes.AddRange(type.GetInterfaces());

        var basedOn = type;
        while (basedOn.BaseType != null)
        {
            toCheckTypes.Add(basedOn.BaseType);
            basedOn = basedOn.BaseType;
        }

        return toCheckTypes.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeToBe);
    }

希望工程为你。

这篇关于json.net:指定字典键转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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