json.net: specify converter for dictionary keys(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 和 CodeB 而不是分别简单的 A 和 B.
But MyEnum values are CodeA, and CodeB instead of simply A and B respectively.
我有一个可以处理转换的自定义转换器.但是如何指定 JsonConverter 与 Dictionary 键一起使用?
I have a custom Converter that can handle conversion. But how do I specify a JsonConverter to use with Dictionary keys?
推荐答案
我认为唯一的方法是为整个 Dictionary 类型或 Dictionary<我的枚举,T>.
I believe the only way is to make a JsonConverter for the whole Dictionary<MyEnum, int> type, or Dictionary<MyEnum, T>. 
字典键不被视为值,不会通过 JsonConverters 运行.TypeConverters 本来是一个解决方案,但是在查看 TypeConverters 之前,将输入默认字符串到枚举转换.
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:为字典键指定转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:json.net:为字典键指定转换器
				
        
 
            
        - C# 通过连接字符串检索正确的 DbConnection 对象 2022-01-01
 - 是否可以在 .Net 3.5 中进行通用控件? 2022-01-01
 - 为什么 C# 中的堆栈大小正好是 1 MB? 2022-01-01
 - 在 C# 中异步处理项目队列 2022-01-01
 - Windows 喜欢在 LINUX 中使用 MONO 进行服务开发? 2022-01-01
 - CanBeNull和ReSharper-将其用于异步任务? 2022-01-01
 - 在 LINQ to SQL 中使用 contains() 2022-01-01
 - Azure Active Directory 与 MVC,客户端和资源标识同一 2022-01-01
 - 带问号的 nvarchar 列结果 2022-01-01
 - 使用 rss + c# 2022-01-01
 
						
						
						
						
						