JSON.Net序列化枚举为字符串默认情况下字典 - 如何使它序列为int? [英] JSON.Net serializing Enums to strings in dictionaries by default - how to make it serialize to int?

查看:120
本文介绍了JSON.Net序列化枚举为字符串默认情况下字典 - 如何使它序列为int?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我的序列化的JSON最终成为

  {性别:1,说文解字:{男 :100,女:200}} 

即为什么在枚举序列化到自己的价值,但是当它们形成他们关键它们转换为他们的关键字典?



我如何让他们在字典整数,为什么心不是这种默认的行为?



标识期待下面的输出

  {性别:1,说文解字:{0:100,1:200}} 

感谢

 公共无效美孚()
{
变种的TestClass =新识别TestClass();
testClass.Gender = Gender.Female;
testClass.Dictionary.Add(Gender.Male,100);
testClass.Dictionary.Add(Gender.Female,200);

VAR serializeObject = JsonConvert.SerializeObject(识别TestClass);

// serializeObject == {性别:1,说文解字:{男:100,女:200}}
}

酒店的公共枚举性别
{
男= 0,
女= 1
}

公共类识别TestClass
{
公性别性别{搞定;组; }
公众的IDictionary<性别,INT>字典{搞定;组; }

公众识别TestClass()
{
this.Dictionary =新词典<性别,INT>();
}
}
}


解决方案

之所以作为属性值时使用,而是作为字典键一起使用时,它是序列化到其字符串表示性别枚举序列化到它的价值如下:




  • 在财产价值JSON.NET串行使用首先写入属性名,之后的属性值。对于您发布的例子,JSON.NET会写性别作为属性名称(注意,这将一个字符串),比将尽力解决该属性的值。该属性的值是JSON.NET处理为的Int32 ,并将其写入枚举


  • 的数字表示枚举类型
  • 在序列化字典,键被写成属性名的,所以JSON.NET串行写枚举的字符串表示。如果切换类型的键和值的字典(词典< INT,性别> 而不是词典<性别,INT> ,你会验证枚举将与其的Int32 表示被序列化。




要达到你想要与你贴,你需要编写自定义的 JsonConverter 的字典属性。像这样的例子是什么

 公共类DictionaryConverter:JsonConverter 
{

公共覆盖无效WriteJson(JsonWriter作家,对象的值,JsonSerializer串行)
{
VAR词典=(词典<性别,INT>)值;

writer.WriteStartObject();

的foreach(KeyValuePair<性别,INT>对在字典)
{
writer.WritePropertyName(((int)的pair.Key)的ToString());
writer.WriteValue(对。值);
}

writer.WriteEndObject();
}

公众覆盖对象ReadJson(JsonReader读者,类型的objectType,对象existingValue,JsonSerializer串行)
{
VAR jObject = JObject.Load(读卡器);

VAR maleValue = int.Parse(jObject [((int)的Gender.Male)的ToString()]的ToString());
变种femaleValue = int.Parse(jObject [((int)的Gender.Female)的ToString()]的ToString());

(existingValue作为字典<性别,INT>)。添加(Gender.Male,maleValue);
(existingValue作为字典<性别,INT>)。添加(Gender.Female,femaleValue);

返回existingValue;
}

公众覆盖布尔CanConvert(类型的objectType)
{
返回的typeof(IDictionary的<性别,INT>)==的objectType;
}
}

和在识别TestClass :

 公共类识别TestClass 
{
公共性别性别{得到;组; }
[JsonConverter(typeof运算(DictionaryConverter))]
公众的IDictionary<性别,INT>字典{搞定;组; }

公众识别TestClass()
{
this.Dictionary =新词典<性别,INT>();
}
}

在呼吁系列化以下行:

  VAR serializeObject = JsonConvert.SerializeObject(识别TestClass); 

您会得到所需要的输出:

  {性别:1,说文解字:{0:100,1:200}} 


Why does my serialized JSON end up as

{"Gender":1,"Dictionary":{"Male":100,"Female":200}}

i.e. why do the enums serialize to their value, but when they form they key to the dictionary they are converted to their key?

How do I make them be ints in the dictionary, and why isnt this the default behaviour?

Id expect the following output

{"Gender":1,"Dictionary":{"0":100,"1":200}}

thanks

    public void foo()
    {
        var testClass = new TestClass();
        testClass.Gender = Gender.Female;
        testClass.Dictionary.Add(Gender.Male, 100);
        testClass.Dictionary.Add(Gender.Female, 200);

        var serializeObject = JsonConvert.SerializeObject(testClass);

        // serializeObject == {"Gender":1,"Dictionary":{"Male":100,"Female":200}}
    }

    public enum Gender
    {
        Male = 0,
        Female = 1
    }

    public class TestClass
    {
        public Gender Gender { get; set; }
        public IDictionary<Gender, int> Dictionary { get; set; }

        public TestClass()
        {
            this.Dictionary = new Dictionary<Gender, int>();
        }
    }
}

解决方案

The reason why Gender enum is serialized to its value when used as property value, but it is serialized to its string representation when used as dictionary key is the following:

  • When used as property value JSON.NET serializer first writes the property name and after that the property value. For the example you posted, JSON.NET will write "Gender" as property name (notice that it writes a string), than will try to resolve the value of the property. The value of the property is of type enum which JSON.NET handles as Int32 and it writes the number representation of the enum

  • When serializing the dictionary, the keys are written as property names, so the JSON.NET serializer writes the string representation of the enum. If you switch the types of the keys and values in the dictionary (Dictionary<int, Gender> instead of Dictionary<Gender, int>, you'll verify that the enum will be serialized with its Int32 representation.

To achieve what you want with the example you posted, you'll need to write custom JsonConverter for the Dictionary property. Something like this:

public class DictionaryConverter : JsonConverter
{

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var dictionary = (Dictionary<Gender, int>) value;

        writer.WriteStartObject();

        foreach (KeyValuePair<Gender, int> pair in dictionary)
        {
            writer.WritePropertyName(((int)pair.Key).ToString());
            writer.WriteValue(pair.Value);
        }

        writer.WriteEndObject();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jObject = JObject.Load(reader);

        var maleValue = int.Parse(jObject[((int) Gender.Male).ToString()].ToString());
        var femaleValue = int.Parse(jObject[((int)Gender.Female).ToString()].ToString());

        (existingValue as Dictionary<Gender, int>).Add(Gender.Male, maleValue);
        (existingValue as Dictionary<Gender, int>).Add(Gender.Female, femaleValue);

        return existingValue;
    }

    public override bool CanConvert(Type objectType)
    {
        return typeof (IDictionary<Gender, int>) == objectType;
    }
}

and decorate the property in the TestClass:

public class TestClass
{
    public Gender Gender { get; set; }
    [JsonConverter(typeof(DictionaryConverter))]
    public IDictionary<Gender, int> Dictionary { get; set; }

    public TestClass()
    {
        this.Dictionary = new Dictionary<Gender, int>();
    }
}

When calling the following line for serialization:

var serializeObject = JsonConvert.SerializeObject(testClass);

you'll get the desired output:

{"Gender":1,"Dictionary":{"0":100,"1":200}}

这篇关于JSON.Net序列化枚举为字符串默认情况下字典 - 如何使它序列为int?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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