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

Json.NET需要反序列化时的所有属性,json,json.net,Json,Json.net,在Json.NET中,如何在反序列化时生成所需的所有属性?我知道我可以通过消息上的属性来实现这一点,但我不想这样做。主要是因为它需要我的消息库承担外部依赖 我尝试了MissingMemberHandling.Error设置,但它与我想要的相反。我同意JSON有额外的属性。我希望它在JSON中缺少任何目标对象属性时失败 实际上,我正在反序列化F#记录,而且属性通常不能为null。(在代码中不能通过正常方式将其赋值为null。)但当数据丢失时,Json.NET会在封面下愉快地将属性默认为null

在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
开放系统
打开Newtonsoft.Json
打开Newtonsoft.Json.Serialization
类型要求ReallPropertiesContractResolver()=
继承DefaultContractResolver()
重写me.CreateObjectContract(objectType:Type)=
let contract=base.CreateObjectContract(objectType)

contract.ItemRequired如果您的模型具有您的JSON可能忽略的属性,并且您希望这是一个错误,请将该属性添加到类中:

类型:

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

所需的可能值为:

  • 默认值:该属性不是必需的。默认状态
  • AllowNull:属性必须在JSON中定义,但可以是空值
  • 始终:属性必须在JSON中定义,并且不能为空值
  • DisallowNull:该属性不是必需的,但不能为空值[如果存在]。(Json.NET及更高版本。)
该设置是继承的,因此可以添加到泛型基类

更新

要对所有对象全局执行此操作,请将子类化,并将
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() };
注:

  • 如果您的f#成员是
    可选的
    时不需要JSON属性,请参见此问题和问题

  • 此协定冲突解决程序将默认设置
    Required。始终
    应用于所有对象属性,但直接应用时不会覆盖。如果需要,请参阅例如

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

  • 你可能想


    • 我知道我在这里聚会迟到了,但是。。。接受的答案强制所有属性都可用,这对于您的记录包含与
      NullValueHandling相结合的选项类型的情况可能不太好。忽略
      JsonSerializerSettings
      上的
      参数。在这种情况下,您将需要存在选项类型,这太有限了。我们发现此解决方案适合我们:

      type RequireAllPropertiesContractResolver() =
          inherit CamelCasePropertyNamesContractResolver()
      
          override __.CreateProperty(memb, serialization) =
              let prop = base.CreateProperty(memb, serialization)
              let isRequired = not (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() = typedefof<option<_>>)
              if isRequired then prop.Required <- Required.Always
              prop
      
      类型要求ReallPropertiesContractResolver()=
      继承CamelCasePropertyNamesContractResolver()
      重写_uu.CreateProperty(memb,序列化)=
      让prop=base.CreateProperty(memb,序列化)
      让isRequired=not(prop.PropertyType.IsGenericType&&prop.PropertyType.GetGenericTypeDefinition()=typedefof)
      
      如果需要,那么在所有类及其子类中添加属性是不可能的。在这一点上,将使用try/catch中的数据的调用包装为null引用异常更容易,这是我目前被迫做的,而不是在源位置捕获它。也许我误解了你的问题,我以为你反对包装所有属性?标记所有类比标记所有属性要少一点工作,但是我的消息库必须依赖于Json.NET,因为它目前没有其他依赖项。此外,F#记录不能从基类继承。我真的需要一种方法来强制Json.NET这样做。这对我来说非常有效,你知道有没有一种方法可以在一个错误中获得所有缺失属性的列表?现在,我需要运行它,找到第一个错误,修复,然后继续运行,这是一个乏味的过程。值得注意的是,这是双向的,这意味着如果对象具有null属性,序列化将失败。我正在努力找出如何在ASP.NET Core 2 Web API中使用不同的ContractResolver进行序列化和反序列化。听起来很像。是的,你是对的。我不知道为什么在几个小时的谷歌搜索后我找不到这个答案
      type RequireAllPropertiesContractResolver() =
          inherit CamelCasePropertyNamesContractResolver()
      
          override __.CreateProperty(memb, serialization) =
              let prop = base.CreateProperty(memb, serialization)
              let isRequired = not (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() = typedefof<option<_>>)
              if isRequired then prop.Required <- Required.Always
              prop