如何用System.Text.Json模拟Newtonsoft对ConcurrentDictionary的自定义序列化?
使用System.Text.Json实现ConcurrentDictionary的自定义项序列化
在Newtonsoft.Json中,我们可以通过ItemConverterType为ConcurrentDictionary的泛型值类型指定自定义序列化器,示例代码如下:
[JsonProperty(PropertyName = "substances", ItemConverterType = typeof(SaturationJsonConverter))] protected ConcurrentDictionary<string, Saturation> Substances { get; } = new();
System.Text.Json没有直接对应ItemConverterType的特性参数,可通过以下两种方式实现相同效果:
方式一:全局为Saturation类指定转换器
如果希望所有用到Saturation类型的序列化场景都使用自定义转换器,直接在Saturation类上标记JsonConverter特性,属性仅需指定名称:
// 为自定义类绑定全局序列化转换器 [JsonConverter(typeof(SaturationJsonConverter))] public class Saturation { // 类成员定义 } // 属性定义 [JsonPropertyName("substances")] protected ConcurrentDictionary<string, Saturation> Substances { get; } = new();
方式二:仅为当前字典属性指定转换器
如果只想让这个特定的ConcurrentDictionary实例使用自定义转换器,不影响其他Saturation的序列化行为,需为该字典类型创建专属转换器:
- 实现字典转换器:
public class ConcurrentDictionarySaturationConverter : JsonConverter<ConcurrentDictionary<string, Saturation>> { private readonly JsonConverter<Saturation> _saturationConverter = new SaturationJsonConverter(); public override ConcurrentDictionary<string, Saturation> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartObject) throw new JsonException("JSON格式错误,预期对象起始标记"); var dict = new ConcurrentDictionary<string, Saturation>(); while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) return dict; if (reader.TokenType != JsonTokenType.PropertyName) throw new JsonException("JSON格式错误,预期属性名"); var key = reader.GetString(); reader.Read(); var value = _saturationConverter.Read(ref reader, typeof(Saturation), options); dict.TryAdd(key, value); } throw new JsonException("JSON格式不完整"); } public override void Write(Utf8JsonWriter writer, ConcurrentDictionary<string, Saturation> value, JsonSerializerOptions options) { writer.WriteStartObject(); foreach (var kvp in value) { writer.WritePropertyName(kvp.Key); _saturationConverter.Write(writer, kvp.Value, options); } writer.WriteEndObject(); } }
- 在属性上引用该转换器:
[JsonPropertyName("substances")] [JsonConverter(typeof(ConcurrentDictionarySaturationConverter))] protected ConcurrentDictionary<string, Saturation> Substances { get; } = new();
内容的提问来源于stack exchange,提问作者Glenn
相关产品推荐
相关产品推荐

