当前位置: 首页 > 知识库问答 >
问题:

如何使DefaultValueHandling仅适用于某些类或成员?

后源
2023-03-14

我需要让对象的某些部分序列化默认值,而有些部分不序列化。

在下面的帖子中,我了解了如何根据类型做到这一点:Json。NET:如何使DefaultValueHandling仅适用于某些类型?

但是这个解决方案只适用于类型,不会是递归的。

预期行为:

{
  {
    "keepDefaults" : {
      "prop1" : true,
      "prop2" : false,
    },
    "ignoreDefaults" : {
      "prop3" : true,
      "prop4" : false,
    }
}

重新序列化时:

  {
    "keepDefaults" : {
      "prop1" : true,
      "prop2" : false
    },
    "ignoreDefaults" : {
      "prop3" : true
    }
}

ContractProvider中是否有我可以重写的内容,或者我可以添加到成员或类中的属性来选择DefaultValueHandling?

共有1个答案

陈斌蔚
2023-03-14

受引用帖子中@dbc的解决方案的启发,我对其进行了调整,以将DefaultValueHandling应用于整个类。

public class DefaultValueContractResolver : DefaultContractResolver
{
    readonly Dictionary<Type, DefaultValueHandling> _overrides = new Dictionary<Type, DefaultValueHandling>();

    public DefaultValueContractResolver(IEnumerable<KeyValuePair<Type, DefaultValueHandling>> overrides = null) : base()
    {
        _overrides = overrides?.ToDictionary(p => p.Key, p => p.Value) ?? _overrides;
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
        if (property.DefaultValueHandling == null)
        {
            if(_overrides.TryGetValue(property.DeclaringType, out DefaultValueHandling handling))
                property.DefaultValueHandling = handling;
        }
    
        return property;
    }
}

然后我可以这样序列化:

var keepDefaults = new KeepDefaults
{
    Prop1 = true,
    Prop2 = false
};

var ignoreDefaults = new IgnoreDefaults
{
    Prop3 = true,
    Prop4 = false
};

var jsSettings = new JsonSerializerSettings
{
    //DefaultValueHandling = DefaultValueHandling.Populate,
    ContractResolver = new DefaultValueContractResolver(
        new Dictionary<Type, DefaultValueHandling>
        { 
            { typeof(IgnoreDefaults), DefaultValueHandling.Ignore } ,
            { typeof(KeepDefaults), DefaultValueHandling.Populate } 
        }),
    Converters = new List<JsonConverter> { new Newtonsoft.Json.Converters.StringEnumConverter() },
    Formatting = Formatting.Indented
};



var json1 = JsonConvert.SerializeObject(keepDefaults, settings);
var json2 = JsonConvert.SerializeObject(ignoreDefaults, settings);

瞧,我得到了预期的结果。

 类似资料:
  • 问题内容: 我有一个包含几个容器的容器。其中三个用于我的应用程序(客户端,服务器和数据库),其余用于各种开发工具(例如psql,npm,manage.py等)。当我完成所有这些操作时,但是我只希望三个主要功能开始。由于已指定了链接,因此只能从这三个开始,但输出仅来自该一个容器。因此,有没有一种方法可以执行以下任一操作: 告诉docker-compose哪个容器应该由以下对象启动 从所有链接的容器获

  • 问题内容: 我有一些通用的设置代码,已将这些代码分解为标记为的方法。但是,不必为每个测试都运行所有这些代码。有没有一种标记方式,使得该方法仅在某些测试之前运行? 问题答案: 只需将不需要安装代码的测试移到单独的测试类中即可。如果您有一些测试通用的其他代码,可以帮助保留这些代码,请将其移到帮助程序类中。

  • REST API请求:EmployeeRequest。java id、名称、sal、位置-- 员工负责。java id、名称、sal、位置-- /api/employee 我不想在回复中使用除ID以外的其他字段 实际:`{id:“123”,“name:“null”,“sal:“null”,“location:“null”}但我只想要response id,而不是POST response的其他字段

  • 我的WordPress博客中有几个类别。所有帖子都可以通过domain.tld/post-title获得。但现在我需要不同的网址为某些主题。 示例: blog>domain.tld/post-title 类别1>域.tld/category-1/post-title 类别2>域.tld/category-2/post-title 类别3>域.tld/post-title 我不想使用插件,而是通过c

  • 我有一个应用程序,可以更改某些元素的字体。这对大多数人来说都很好,但可能有0.5%的人在尝试更改字体时会出现异常。堆栈跟踪的重要部分是: 正如我所说,它适用于大多数人,所以我认为这不是字体文件或我的代码的问题。关于如何解决这个问题,有什么建议吗? 编辑:这是我的代码:

  • 我正在使用来自openweathermap的json API数据来获取有关特定城市的信息。 几天前还好好的,现在由于某种原因,每个标有塞尔维亚国家代码“RS”的城市都不能工作了。http://api.openweathermap.org/data/2.5/weather?q =塞尔维亚贝尔格莱德 如果我使用其他国家的城市,例如这个,它是有效的:http://api.openweathermap.o