
[英]How can I serialize/deserialize a dictionary with custom keys using Json.Net?
[英]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
没有这样的功能。
那么,您有哪些选择?
您可以修改全局命名策略以逐字序列化字典名称,如序列化字典时保持大小写所示。
您可以继承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在这里。
您可以引入一个自定义的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.