在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()
答案 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() };
注意:
如果您不希望在f#成员optional
时需要JSON属性,请参阅this answer此问题以及问题 Json.NET make property required based on property type < / EM>
答案 1 :(得分:1)
我知道我在这里参加聚会很晚,但是...接受的答案会强制所有属性可用,当您的记录包含与{{ 1}}。在这种情况下,您将需要提供选项类型,这太过局限了。我们发现此解决方案适用于我们:
NullValueHandling.Ignore
我希望它能对某人有所帮助。