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

标签 c# json.net

我有一个类:

 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/

相关文章:

c# - 如何优化 GridView 生成的 ViewState 并保留一些 GridView 相关的功能

c# - 如何将mysql的日期时间转换为asp.net的日期时间

c# - 如何使用 NewtonSoft Json.Net 将 Json 字典反序列化为平面类

c# - 如何忽略生成的 JSON 中的空对象文字?

c# - 通过属性应用时如何将多个参数传递给 JsonConverter?

c# - 在 ServiceStack 的插件上访问 IRequestContext

c# - 在 Linq-to-SQL 中更新记录及其关联关系的一般最佳实践

时间:2019-03-17 标签:c#tooltiphelp

json - 通过 Json.Net 反序列化 F# Map

c# - 使用变量名数组反序列化 JSON