我有一个班级:
public class MyClass
{
public MyEnum Foo{ get; set; }
}
在序列化期间,我想改变
的输出{
"Foo": 1
}
到
{
"Foo": "EnumName"
}
我已经尝试过创建一个IValueProvider,但是每走一步都会遇到死胡同。 (我的场景比声明的要复杂一点;我需要找到一种方法在IContractResolver中完全执行此操作。)
答案 0 :(得分:2)
您可以创建一个继承自custom ContractResolver
的DefaultContractResolver
,自动将StringEnumConverter
应用于枚举或可枚举枚举的每个合约:
public class StringEnumContractResolver : DefaultContractResolver
{
readonly StringEnumConverter converter;
public StringEnumContractResolver() : this(true, false) { }
public StringEnumContractResolver(bool allowIntegerValue, bool camelCaseText)
{
this.converter = new StringEnumConverter { AllowIntegerValues = allowIntegerValue, CamelCaseText = camelCaseText };
}
protected override JsonPrimitiveContract CreatePrimitiveContract(Type objectType)
{
var contract = base.CreatePrimitiveContract(objectType);
var type = Nullable.GetUnderlyingType(contract.UnderlyingType) ?? contract.UnderlyingType;
if (type.IsEnum && contract.Converter == null)
contract.Converter = converter;
return contract;
}
}
注意:
如果枚举类型已应用JsonConverter
,则优先于默认StringEnumConverter
。
将转换器添加到枚举本身的JsonPrimitiveContract
,而不是返回枚举的成员的每个JsonProperty
,确保将转换器应用于集合和词典中的枚举。
IValueProvider
仅提供获取和设置值的方法,因此与转换器相比,此方法不太方便。您需要将枚举值的嵌套序列化和反序列化作为其中的JSON字符串执行,但它不是为此设计的,因此无法访问JSON读取器,编写器或序列化程序。此外,字典值或枚举的集合项没有值提供者。
您可能希望缓存合约解析程序,以获得最佳效果,如here所述。
示例.Net fiddle。