Json.NET序列化Dictionary与KeyValuePair的差异及实现方案
问题1解答
- Json.NET内置了专门针对
Dictionary<TKey, TValue>类型的序列化逻辑,会将字典直接序列化为JSON对象结构:字典的键作为JSON对象的属性名,对应的值作为属性值。 - 而
KeyValuePair<TKey, TValue>是值类型结构体,默认没有特殊的序列化适配,序列化器会按普通POCO类型的规则处理,直接输出它的两个公开属性Key和Value的键值对,所以会得到{"Key":"xxx","Value":"xxx"}的结构。
问题2解答
你可以通过自定义JsonConverter的方式实现需求,步骤如下:
- 首先实现自定义序列化转换器:
public class KeyValuePairConverter : JsonConverter<KeyValuePair<string, object>> { public override void WriteJson(JsonWriter writer, KeyValuePair<string, object> value, JsonSerializer serializer) { writer.WriteStartObject(); writer.WritePropertyName(value.Key); serializer.Serialize(writer, value.Value); writer.WriteEndObject(); } public override KeyValuePair<string, object> ReadJson(JsonReader reader, Type objectType, KeyValuePair<string, object> existingValue, bool hasExistingValue, JsonSerializer serializer) { // 若需要反序列化能力可补充对应逻辑,仅处理序列化时可直接抛出异常 throw new NotImplementedException(); } }
- 在
Foo类的Pair属性上标注转换器特性,指定用自定义转换器处理序列化:
public class Foo { [JsonConverter(typeof(KeyValuePairConverter))] public KeyValuePair<string, object> Pair { get; set; } }
- 序列化后即可得到预期结果,示例:
var foo = new Foo { Pair = new KeyValuePair<string, object>("key 1", "value 1") }; var json = JsonConvert.SerializeObject(foo); // 输出结果为 {"Pair":{"key 1":"value 1"}}
如果需要全局生效不用逐个属性加特性,也可以在序列化时把转换器添加到序列化配置的Converters集合中:
var settings = new JsonSerializerSettings(); settings.Converters.Add(new KeyValuePairConverter()); var json = JsonConvert.SerializeObject(foo, settings);
内容的提问来源于stack exchange,提问作者Mohamad Mustafa
相关产品推荐
相关产品推荐

