一尘不染

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

json

在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()

阅读 270

收藏
2020-07-27

共1个答案

一尘不染

如果您的 模型 具有 JSON
可能会忽略的属性,而您希望它是一个错误,请将属性添加[JsonObject(ItemRequired=Required.Always)]到类中:

类型:必填

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

可能的值为Required

  • 默认值:该属性不是必需的。默认状态。
  • AllowNull:该属性必须在JSON中定义,但可以为空值。
  • 始终:该属性必须在JSON中定义,并且不能为空值。
  • DisallowNull:该属性不是必需的,但不能为null值(如果存在)。(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() };

笔记:
* 如问题中所述,该设置MissingMemberHandling = MissingMemberHandling.Error解决了一个补充问题:如果您的 JSON 可能具有您的 模型 忽略的属性,并且您希望它是一个错误,请使用MissingMemberHandling.Error。请参阅:MissingMemberHandling设置

2020-07-27