繁体   English   中英

如何使 Json 序列化忽略字典键

[英]How to make Json Serialize ignore dictionary keys

我正在尝试序列化 class 中的字典,即使我将ProcessDictionaryKeys参数设置为 false, CustomAttributes字典中的键也会被格式化。

我添加了[JsonProperty]如下所示:

[JsonProperty(NamingStrategyType = typeof(SnakeCaseNamingStrategy), NamingStrategyParameters = new object[] { false, false })]
public IDictionary<string, string> CustomAttributes { get; set; }

我的 CustomAttributes 数据如下所示:

CustomAttributes = new Dictionary<string, string>()
{
    {"Custom Attribute 1", "1"},
    {"CustomAttribute 2", "2"}
}

和产生的 JSON 看起来像:

custom_attributes\":{\"custom Attribute 1\":\"1\",\"customAttribute 2\":\"2\"

如您所见,每个字典键的第一个字母都没有大写。 我怎样才能阻止这种情况发生?

编辑:将ProcessDictionaryKeys参数更改为 true 似乎没有任何区别。

仅使用问题中的代码不会重现问题,如演示小提琴 #1 中所示

相反,您必须使用JsonSerializerSettings.ContractResolver.NamingStrategy.ProcessDictionaryKeys = true的一些全局序列化程序设置进行序列化,例如CamelCasePropertyNamesContractResolver

var settings = new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver(),
};
var json = JsonConvert.SerializeObject(root, Formatting.Indented, settings);

演示小提琴#2在这里

假设这是正确的, [JsonProperty(NamingStrategyType = typeof(SnakeCaseNamingStrategy), NamingStrategyParameters = new object[] { false, false })]不会导致字典键被逐字序列化的原因是JsonPropertyAttribute.NamingStrategyType仅适用于属性name 本身(此处为CustomAttributes )而不是属性items的属性名称。 如果您想对属性的项目应用命名策略,则需要类似ItemNamingStrategyType的东西——但JsonPropertyAttribute没有这样的功能。

那么,您有哪些选择?

  1. 您可以修改全局命名策略以逐字序列化字典名称,如序列化字典时保持大小写所示。

  2. 您可以继承Dictionary<TKey, TValue>并将[JsonDictionary(NamingStrategyType = typeof(DefaultNamingStrategy))]应用于它,如Applying JsonDictionary attribute to dictionary答案所示:

     [JsonDictionary(NamingStrategyType = typeof(DefaultNamingStrategy))] public class VerbatimDictionary<TKey, TValue>: Dictionary<TKey, TValue> { }

    然后后来:

     CustomAttributes = new VerbatimDictionary<string, string>() { {"Custom Attribute 1", "1"}, {"CustomAttribute 2", "2"} }

    演示小提琴#3在这里

  3. 您可以引入一个自定义的JsonConverter ,它使用默认命名策略对IDictionary<TKey, TValue>进行序列化。 首先,定义以下转换器:

     public class VerbatimDictionaryConverter<TKey, TValue>: JsonConverter<IDictionary<TKey, TValue>> { [JsonDictionary(NamingStrategyType = typeof(DefaultNamingStrategy))] class VerbatimDictionarySerializationSurrogate: IReadOnlyDictionary<TKey, TValue> { readonly IDictionary<TKey, TValue> dictionary; public VerbatimDictionarySerializationSurrogate(IDictionary<TKey, TValue> dictionary) { if (dictionary == null) throw new ArgumentNullException(nameof(dictionary)); this.dictionary = dictionary; } public bool ContainsKey(TKey key) { return dictionary.ContainsKey(key); } public bool TryGetValue(TKey key, out TValue value) { return dictionary.TryGetValue(key, out value); } public TValue this[TKey key] { get { return dictionary[key]; } } public IEnumerable<TKey> Keys { get { return dictionary.Keys; } } public IEnumerable<TValue> Values { get { return dictionary.Values; } } public int Count { get { return dictionary.Count; } } public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return dictionary.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public override void WriteJson(JsonWriter writer, IDictionary<TKey, TValue> value, JsonSerializer serializer) { serializer.Serialize(writer, new VerbatimDictionarySerializationSurrogate(value)); } public override bool CanRead { get { return false; } } public override IDictionary<TKey, TValue> ReadJson(JsonReader reader, Type objectType, IDictionary<TKey, TValue> existingValue, bool hasExistingValue, JsonSerializer serializer) { throw new NotImplementedException(); } }

    并按如下方式应用:

     [JsonConverter(typeof(VerbatimDictionaryConverter<string, string>))] public IDictionary<string, string> CustomAttributes { get; set; }

    演示小提琴#4在这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM