【问题标题】:Anyway to get JsonConvert.SerializeObject to ignore the JsonConverter attribute on a property?无论如何要让 JsonConvert.SerializeObject 忽略属性上的 JsonConverter 属性?
【发布时间】:2017-08-11 21:16:47
【问题描述】:

我有一门我无法更改的课程:

public enum MyEnum {
    Item1 = 0,
    Item2 = 1
}
public class foo {
    [JsonConverter(typeof(StringEnumConverter))]
    public MyEnum EnumTypes {get; set; }
}

JsonConvert.SerializeObject 的某处将对象序列化,并且由于JsonConverter 属性,它会吐出foo.EnumTypes 的枚举值的名称而不是数字。

有没有办法让JsonConvert.SerializeObject 忽略EnumTypes 属性上的属性?

【问题讨论】:

  • 我认为这取决于您如何使用 foo 类,如果您实际上只是自己序列化 foo 的实例,那么您可以实现一个不使用 StringEnumConverter 的类的版本EnumTypes 字段并在序列化之前复制字段值。您能否提供更多信息来为问题提供更多背景信息?

标签: c# serialization json.net


【解决方案1】:

这是可能的,但过程有点复杂。

基本思想是创建一个自定义ContractResolver 并覆盖其CreateProperty 方法。像这样:

internal sealed class MyContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty( MemberInfo member, MemberSerialization memberSerialization )
    {
        var property = base.CreateProperty( member, memberSerialization );

        if( member.DeclaringType == typeof( foo ) && property.PropertyType == typeof( MyEnum ) )
        {
            property.Converter = null;
        }

        return property;
    }
}

您还需要实际实例化此类并将其传递给您的序列化器/反序列化器。这看起来像什么取决于你是如何进行序列化的,所以我不能保证一个相关的例子来说明如何使用它。

如果您只是使用静态SerializeObject 方法:

JsonConvert.SerializeObject( valueToSerialize, new SerializerSettings { ContractResolver = new MyContractResolver() } );

【讨论】:

  • 这看起来很有希望。如何将它传递给序列化程序?你有例子吗?
  • @AngryHacker 就像我说的,这完全取决于你如何进行序列化。有许多不同的方法可以做到这一点。我为ContractResolver 链接到的文档有一个示例,说明您可以这样做,但这不是唯一的方法。我会用一个例子来编辑答案,但我不能保证它会为你工作。
  • 我在发表评论 5 秒后发现了它。它实际上正在做我需要它做的事情。完美。
【解决方案2】:

Kyle 的回答是一个很好的起点。它在这个来自问题的具体简单示例中运行良好。但对我来说,它对嵌套属性递归不起作用,至少在 newtonsoft.json v12.0.3 中是这样。看看我发现的 DefaultContractResolver 中还有什么可以覆盖

public virtual JsonContract ResolveContract(Type type);

它适用于嵌套属性:

    internal sealed class NumericEnumContractResolver : DefaultContractResolver
    {
        private Type _stringEnumConverterType = typeof(StringEnumConverter);

        protected override JsonConverter ResolveContractConverter(Type objectType)
        {
            var converter = base.ResolveContractConverter(objectType);

            if ((converter != null) &&
                (converter.GetType() == _stringEnumConverterType))
            {
                converter = null;
            }

            return converter;
        }
    }

和示例用法:

JsonConvert.SerializeObject(
    myObject,
    new SerializerSettings
    {
        ContractResolver = new NumericEnumContractResolver()
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    相关资源
    最近更新 更多