如何使Json Serialize忽略字典键 [英] How to make Json Serialize ignore dictionary keys
问题描述
我正在尝试在一个类中对字典进行序列化,并且即使我将ProcessDictionaryKeys
参数设置为false,也要格式化CustomAttributes
字典中的键.
I'm trying to serialize a dictionary within a class and the keys inside the CustomAttributes
dictionary are getting formatted even though I've provided the ProcessDictionaryKeys
parameter as false.
我添加了[JsonProperty]
,如下所示:
[JsonProperty(NamingStrategyType = typeof(SnakeCaseNamingStrategy), NamingStrategyParameters = new object[] { false, false })]
public IDictionary<string, string> CustomAttributes { get; set; }
我的CustomAttributes数据如下:
my CustomAttributes data looks like this:
CustomAttributes = new Dictionary<string, string>()
{
{"Custom Attribute 1", "1"},
{"CustomAttribute 2", "2"}
}
和生成的JSON如下:
and the JSON which is produced looks like:
custom_attributes\":{\"custom Attribute 1\":\"1\",\"customAttribute 2\":\"2\"
如您所见,每个字典键的首字母都没有大写.我该如何阻止这种情况的发生?
As you can see, the first letter of each of the dictionary keys are being uncapitalised. How can I stop this from happening?
将ProcessDictionaryKeys
参数更改为true似乎没有任何区别.
Changing the ProcessDictionaryKeys
parameter to true doesn't seem to make any difference.
推荐答案
仅演示小提琴#1 相反,您必须使用 CamelCasePropertyNamesContractResolver
:
Instead, you must be serializing with some global serializer settings for which JsonSerializerSettings.ContractResolver.NamingStrategy.ProcessDictionaryKeys = true
such as 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
仅适用于属性名称本身(此处为CustomAttributes
),不适用于属性的项.如果要对属性项应用命名策略,则需要类似ItemNamingStrategyType
的内容,但是
Assuming that's correct, the reason that [JsonProperty(NamingStrategyType = typeof(SnakeCaseNamingStrategy), NamingStrategyParameters = new object[] { false, false })]
does not cause the dictionary keys to be serialized verbatim is that JsonPropertyAttribute.NamingStrategyType
only applies to the property name itself (here CustomAttributes
) not the property names of property's items. If you wanted to apply a naming strategy to the property's items you would need something like ItemNamingStrategyType
-- but JsonPropertyAttribute
has no such functionality.
那么,您有什么选择?
-
您可以修改全局命名策略,以逐字序列化字典名称,如 序列化字典时保持大小写 .
您可以子类化Dictionary<TKey, TValue>
并应用 [JsonDictionary(NamingStrategyType = typeof(DefaultNamingStrategy))]
,如此答案所示,
You could subclass Dictionary<TKey, TValue>
and apply [JsonDictionary(NamingStrategyType = typeof(DefaultNamingStrategy))]
to it as shown in this answer to 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>
进行序列化.首先,定义以下转换器:
You could introduce a custom JsonConverter
that serializes an IDictionary<TKey, TValue>
with the default naming strategy. First, define the following converter:
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 此处.
这篇关于如何使Json Serialize忽略字典键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!