问题描述
以下类
public class RequestSections:RequestBase
{
public RequestSections(Command c,字典< SectionIdentifier,BigInteger> v):base(c)
{
VERSIONS = v;
}
public Dictionary< SectionIdentifier,BigInteger> VERSIONS {get;组; }
}
使用JSON.NET将其序列化为JSON,并生成以下JSON输出:
{
VERSIONS:{
照片:901,
音乐:902
},
CMD:43
}
问题是 SectionIdentifier
是枚举
,但JSON.NET将它们转换为字符串。
public enum SectionIdentifier
{
照片= 1000,
音乐
}
如何防止JSON.NET转换整数枚举
值到字符串?我只想看到他们的整数表示。
顺便说一下, CMD
$ c> RequestBase 类也是枚举
类型,但不幸的是,它不会转换为字符串。
表示属性名称(键)在对象中必须是字符串。如果您有一个使用枚举值作为键的字典,Json.Net只需在这些值上调用 Convert.ToString()
来获取JSON属性名称。 (这可以在,由 SerializeDictionary()
调用。)
可以覆盖此默认行为,以便Json.Net将将数字枚举字典键写入JSON(当然也可以符合规范)。这可以使用自定义 ContractResolver
或自定义 JsonConverter
完成。在这种情况下,解析器方法可能会更简单一些,所以我将在这里展示。以下是您需要的代码:
class CustomResolver:DefaultContractResolver
{
protected override JsonDictionaryContract CreateDictionaryContract(键入objectType)
{
var contract = base.CreateDictionaryContract(objectType);
var keyType = contract.DictionaryKeyType;
if(keyType.BaseType == typeof(Enum))
{
contract.PropertyNameResolver =
propName => ((int)Enum.Parse(keyType,propName))。ToString();
}
退货合同;
}
}
要序列化,将自定义解析器的一个实例传递给串行器通过这样的设置:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new CustomResolver();
string json = JsonConvert.SerializeObject(foo,settings);
这是一个有创意的演示,表明它有效。您可以注释掉设置解析器以切换行为的行。
class Program
pre>
{
static void Main(string [] args)
{
var dict = new Dictionary< Color,string>
{
{Color.Red,#FF0000},
{Color.Green,#00FF00},
{Color.Blue,#0000FF},
{Color.White,#FFFFFF}
};
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new CustomResolver();
settings.Formatting = Formatting.Indented;
string json = JsonConvert.SerializeObject(dict,settings);
Console.WriteLine(json);
}
枚举颜色{Red = 1,Green = 2,Blue = 3,White = 4}
}
输出:
{
1 :#FF0000,
2:#00FF00,
3:#0000FF,
4:#FFFFFF
}
The following class
public class RequestSections : RequestBase { public RequestSections(Command c, Dictionary<SectionIdentifier, BigInteger> v) : base(c) { VERSIONS = v; } public Dictionary<SectionIdentifier, BigInteger> VERSIONS { get; set; } }
is serialized to JSON using JSON.NET and producing the following JSON output:
{ "VERSIONS": { "Photos": 901, "Music": 902 }, "CMD": 43 }
The problem is that
SectionIdentifier
isenum
but JSON.NET converts them to string.public enum SectionIdentifier { Photos = 1000, Music }
How can I prevent JSON.NET converting integer
enum
values to string? I would like to see their integer representations only.By the way,
CMD
which is residing inRequestBase
class is alsoenum
type, but somehow luckily it is not converted to string.解决方案The JSON spec says that property names (keys) in objects must be strings. If you have a dictionary that uses enum values as keys, Json.Net simply calls
Convert.ToString()
on those values to get the JSON property names. (This can be seen in theGetPropertyName()
method in the source code, which is called bySerializeDictionary()
.)It is possible to override this default behavior so that Json.Net will write numeric enum dictionary keys to the JSON (still as strings, of course, in keeping with the spec). This can be done using either a custom
ContractResolver
or a customJsonConverter
. The resolver approach will probably be a bit simpler in this particular case, so I'll show that here. Here is the code you would need:class CustomResolver : DefaultContractResolver { protected override JsonDictionaryContract CreateDictionaryContract(Type objectType) { var contract = base.CreateDictionaryContract(objectType); var keyType = contract.DictionaryKeyType; if (keyType.BaseType == typeof(Enum)) { contract.PropertyNameResolver = propName => ((int)Enum.Parse(keyType, propName)).ToString(); } return contract; } }
To serialize, pass an instance of the custom resolver to the serializer via the settings like this:
JsonSerializerSettings settings = new JsonSerializerSettings(); settings.ContractResolver = new CustomResolver(); string json = JsonConvert.SerializeObject(foo, settings);
Here is a contrived demo to show that it works. You can comment out the line that sets the resolver to toggle the behavior.
class Program { static void Main(string[] args) { var dict = new Dictionary<Color, string> { { Color.Red, "#FF0000" }, { Color.Green, "#00FF00" }, { Color.Blue, "#0000FF" }, { Color.White, "#FFFFFF" } }; JsonSerializerSettings settings = new JsonSerializerSettings(); settings.ContractResolver = new CustomResolver(); settings.Formatting = Formatting.Indented; string json = JsonConvert.SerializeObject(dict, settings); Console.WriteLine(json); } enum Color { Red = 1, Green = 2, Blue = 3, White = 4 } }
Output:
{ "1": "#FF0000", "2": "#00FF00", "3": "#0000FF", "4": "#FFFFFF" }
这篇关于如何防止Json.NET将枚举转换为字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!