Json.NET需要反序列化的所有属性

时间:2015-04-15 16:15:57

标签: json json.net

在Json.NET中,如何在反序列化时使所有属性成为必需?我知道我可以使用消息上的属性来执行此操作,但我不想这样做。主要是因为它需要我的消息库来承担外部依赖。

我尝试了MissingMemberHandling.Error设置,但它与我想要的相反。我对JSON有额外的属性没关系。我希望它在JSON中缺少任何目标对象属性时失败。

我实际上反序列化为F#记录,无论如何,属性通常不能为null。 (它们不能通过代码中的常规方式赋值为null。)但是当数据丢失时,Json.NET很乐意将属性默认为null。


接受答案的F#版本

解析器

open System
open Newtonsoft.Json
open Newtonsoft.Json.Serialization

type RequireAllPropertiesContractResolver() =
    inherit DefaultContractResolver()

    override me.CreateObjectContract(objectType:Type) =
        let contract = base.CreateObjectContract(objectType)
        contract.ItemRequired <- new Nullable<Required>(Required.Always)
        contract

在设置中

let settings = new JsonSerializerSettings() // default settings
...
settings.ContractResolver <- new RequireAllPropertiesContractResolver()

2 个答案:

答案 0 :(得分:23)

将属性[JsonObject(ItemRequired=Required.Always)]添加到您的课程中:

  

输入:Required

     

一个值,指示是否需要对象的属性。

Required的可能值为:

  
      
  • 默认值:不需要该属性。默认状态。
  •   
  • AllowNull:该属性必须以JSON定义,但可以为空值。
  •   
  • 始终:必须以JSON定义属性,且不能为空值。
  •   
  • DisallowNull:该属性不是必需的,但不能为空值[如果存在]。 (Json.NET 8.0.1及更高版本。)
  •   

该设置是继承的,因此可以添加到通用基类。

<强>更新

要对所有对象进行全局操作,请为DefaultContractResolver创建子类并将ItemRequired标志添加到所有对象协定中:

public class RequireObjectPropertiesContractResolver : DefaultContractResolver
{
    protected override JsonObjectContract CreateObjectContract(Type objectType)
    {
        var contract = base.CreateObjectContract(objectType);
        contract.ItemRequired = Required.Always;
        return contract;
    }
}

然后,在设置中:

var settings = new JsonSerializerSettings { ContractResolver = new RequireObjectPropertiesContractResolver() };

注意:

答案 1 :(得分:1)

我知道我在这里参加聚会很晚,但是...接受的答案会强制所有属性可用,当您的记录包含与{{ 1}}。在这种情况下,您将需要提供选项类型,这太过局限了。我们发现此解决方案适用于我们:

NullValueHandling.Ignore

我希望它能对某人有所帮助。