Json.NET自定义类为键的字典如何实现预期键值序列化格式
解决方案
问题原因
你当前使用的转换器逻辑是将字典转换为List<KeyValuePair<TKey, TValue>>进行序列化,Json.NET默认会将KeyValuePair类型序列化为包含Key和Value两个属性的对象,这就是你当前得到不符合预期格式的原因。
调整后的转换器实现
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Collections.Generic; using System.Linq; public class CustomDictionaryConverter<TKey, TValue> : JsonConverter { public override bool CanConvert(Type objectType) => objectType == typeof(Dictionary<TKey, TValue>); public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var dict = (Dictionary<TKey, TValue>)value; writer.WriteStartObject(); foreach (var kv in dict) { // 利用已注册的转换器序列化键,提取为字符串形式的属性名 var keyToken = JToken.FromObject(kv.Key, serializer); string propertyName = keyToken.Type == JTokenType.String ? keyToken.Value<string>() : keyToken.ToString(); writer.WritePropertyName(propertyName); // 序列化值,自动复用对应转换器 serializer.Serialize(writer, kv.Value); } writer.WriteEndObject(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var resultDict = new Dictionary<TKey, TValue>(); var jsonObj = JObject.Load(reader); foreach (var property in jsonObj.Properties()) { // 将属性名反序列化为自定义键类型 TKey key = JsonConvert.DeserializeObject<TKey>(JsonConvert.ToString(property.Name), serializer.Converters.ToArray()); // 将属性值反序列化为自定义值类型 TValue value = property.Value.ToObject<TValue>(serializer); resultDict.Add(key, value); } return resultDict; } }
注意事项
- 你已经实现的TKey专属JsonConverter需要支持从字符串反序列化、以及序列化输出为合法的JSON属性名字符串,否则会出现格式错误
- 该实现会自动复用你为TKey、TValue注册的专属序列化/反序列化逻辑,无需额外适配
- 如需处理空字典、null值等特殊场景,可以在遍历逻辑前增加对应判空分支
内容的提问来源于stack exchange,提问作者Vic
相关产品推荐
相关产品推荐

