我正在尝试对类中的字典进行序列化,即使我将CustomAttributes
参数设置为false,ProcessDictionaryKeys
字典中的键也会被格式化。
我添加了[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似乎没有什么区别。
答案 0 :(得分:1)
问题并不能仅用演示小提琴#1 here中所示的问题中的代码来重现。
相反,您必须使用JsonSerializerSettings.ContractResolver.NamingStrategy.ProcessDictionaryKeys = true
的全局全局序列化程序设置进行序列化,例如CamelCasePropertyNamesContractResolver
:
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
};
var json = JsonConvert.SerializeObject(root, Formatting.Indented, settings);
演示小提琴#2 here。
假设是正确的,[JsonProperty(NamingStrategyType = typeof(SnakeCaseNamingStrategy), NamingStrategyParameters = new object[] { false, false })]
不会导致字典键逐字序列化的原因是JsonPropertyAttribute.NamingStrategyType
仅适用于属性名称本身(此处为{{ 1}}),而不是属性的项的属性名称。如果要对属性项应用命名策略,则需要类似CustomAttributes
的东西,但是JsonPropertyAttribute
没有这样的功能。
那么,您有什么选择?
您可以修改全局命名策略,以逐字序列化字典名称,如 Keep casing when serializing dictionaries 中所示。
您可以将ItemNamingStrategyType
子类化,并将[JsonDictionary(NamingStrategyType = typeof(DefaultNamingStrategy))]
应用于{em> this answer 中的Applying JsonDictionary attribute to dictionary:
Dictionary<TKey, TValue>
再后来:
[JsonDictionary(NamingStrategyType = typeof(DefaultNamingStrategy))]
public class VerbatimDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
}
演示小提琴#3 here。
您可以引入一个custom JsonConverter
,该序列使用默认的命名策略对CustomAttributes = new VerbatimDictionary<string, string>()
{
{"Custom Attribute 1", "1"},
{"CustomAttribute 2", "2"}
}
进行序列化。首先,定义以下转换器:
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(); }
}
演示小提琴#4 here。