我正在尝试序列化一个类中的字典,并且 CustomAttributes
字典中的键正在格式化,即使我提供的 ProcessDictionaryKeys
参数为 false。
我添加了 [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 似乎没有任何区别。
最佳答案
如 demo fiddle #1 here 所示,仅使用问题中的代码不会重现问题。 .
相反,您必须使用一些全局序列化程序设置进行序列化 JsonSerializerSettings.ContractResolver.NamingStrategy.ProcessDictionaryKeys = true
例如 CamelCasePropertyNamesContractResolver
:
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
};
var json = JsonConvert.SerializeObject(root, Formatting.Indented, settings);
演示 fiddle #2 here .
假设这是正确的,[JsonProperty(NamingStrategyType = typeof(SnakeCaseNamingStrategy), NamingStrategyParameters = new object[] { false, false })]
的原因不会导致字典键被逐字序列化的是 JsonPropertyAttribute.NamingStrategyType
仅适用于属性名称本身(此处为 CustomAttributes
),不适用于属性项目 的属性名称。如果您想对属性的项目应用命名策略,您需要像 ItemNamingStrategyType
这样的东西-- 但是 JsonPropertyAttribute
没有这样的功能。
那么,您有哪些选择?
您可以修改全局命名策略以逐字序列化字典名称,如 Keep casing when serializing dictionaries 所示。 。
你可以继承
Dictionary<TKey, TValue>
并申请[JsonDictionary(NamingStrategyType = typeof(DefaultNamingStrategy))]
如 this answer 所示给 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"} }
演示 fiddle #3 here .
你可以介绍一个 custom
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; }
演示 fiddle #4 here .
关于c# - 如何让 Json Serialize 忽略字典键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58501943/