通过自定义IContractResolver修改/添加属性

c# json.net

346 观看

1回复

83 作者的声誉

我有一堂课:

 public class MyClass
 {
    public MyEnum Foo{ get; set; }
 }

在序列化期间,我想更改输出

{
   "Foo": 1
}

{
   "Foo": "EnumName"
}

我曾尝试创建一个IValueProvider,但我尝试的每种方式都陷入僵局。(我的场景比说明的要复杂一些;我需要找到一种完全在IContractResolver中实现此目的的方法。)

作者: Stringer Bell 的来源 发布者: 2017 年 9 月 15 日

回应 1


2

60889 作者的声誉

决定

您可以创建一个自定义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应用,则优先于default StringEnumConverter

  • 将转换器添加到JsonPrimitiveContract枚举本身的,而不是添加到每个JsonProperty返回枚举的成员的转换器,可确保将转换器应用于集合和词典中的枚举。

  • IValueProvider仅仅提供了获取和设置值,因此是这个目的比转换器不太方便。您将需要对枚举值进行嵌套的序列化和反序列化,将其作为其中的JSON字符串,但是它不是为此设计的,因此无法访问JSON读取器,写入器或序列化器。此外,没有用于枚举的字典值或收集项的值提供程序。

  • 你可能想缓存以获得最佳性能的合同解析器的解释在这里

样本.Net小提琴

作者: dbc 发布者: 2017 年 9 月 15 日
32x32