我有一个类:
public class MyClass
{
public MyEnum Foo{ get; set; }
}
在序列化期间,我想更改输出
{
"Foo": 1
}
到
{
"Foo": "EnumName"
}
我尝试创建一个 IValueProvider,但每次都遇到了死胡同。 (我的场景比所述的要复杂一些;我需要找到一种方法来完全在 IContractResolver 内完成此操作。)
最佳答案
您可以创建一个 custom ContractResolver
继承自DefaultContractResolver
自动应用 StringEnumConverter
枚举或可为 null 的枚举的每个合约:
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 .
关于c# - 通过自定义 IContractResolver 修改/添加属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46231934/