如何使Json Serialize忽略字典键 [英] How to make Json Serialize ignore dictionary keys

查看:152
本文介绍了如何使Json Serialize忽略字典键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在一个类中对字典进行序列化,并且即使我将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.

那么,您有什么选择?

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

您可以子类化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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆