考虑到我们有一种描述参加AB测试结果的类型
public class ABTest
{
[JsonProperty(Required = Required.Always)]
public ulong CountOfAs { get; set; }
[JsonProperty(Required = Required.Always)]
public ulong CountOfBs { get; set; }
[JsonProperty(Required = Required.Always)]
public ulong TotalCount { get; set; }
[JsonProperty(Required = Required.Always)]
[JsonConverter(typeof(SomeCustomTypeJsonConverter))]
public SomeCustomType SomeOtherField { get; set; }
[JsonModelValidation]
public bool IsValid() => CountOfAs + CountOfBs == TotalCount;
}
因此,每次ABTest
实例被反序列化时,我们要验证A组中的人数加上B组中的人数等于参加测试的总人数。
如何在JSON.Net中表达它?外部方法不太适合,因为可以在多个层次结构的任何位置找到此模型。因此,不能仅通过两个单独的步骤对它进行反序列化和验证。而且,我并没有真正将反序列化的对象置于可能无效的状态,因此它应该是默认反序列化的一部分。
答案 0 :(得分:2)
如果您不希望该对象处于可能无效的状态,那么我首先建议使其变为不可变的。
然后您可以使用JsonConstructor
进行验证:
public class ABTest
{
[JsonProperty(Required = Required.Always)]
public ulong CountOfAs { get; }
[JsonProperty(Required = Required.Always)]
public ulong CountOfBs { get; }
[JsonProperty(Required = Required.Always)]
public ulong TotalCount { get; }
[JsonProperty(Required = Required.Always)]
[JsonConverter(typeof(SomeCustomTypeJsonConverter))]
public SomeCustomType SomeOtherField { get; set; }
[JsonConstructor]
public ABTest(ulong countOfAs, ulong countOfBs, ulong totalCount, SomeCustomType someOtherField)
{
if (totalCount != countOfAs + countOfBs)
throw new ArgumentException(nameof(totalCount));
CountOfAs = countOfAs;
CountOfBs = countOfBs;
TotalCount = totalCount;
SomeOtherField = someOtherField;
}
}
这为您提供了一个单一的构造函数,Json.NET和代码库的其余部分都可以使用该构造函数进行验证。