考虑我们有一种描述参与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
的实例都必须进行验证,我们希望验证B组A组中的人数加上B组的人数等于参与测试的总数。
如何在json.net中表达它?外部方法不太合适,因为可以在多个层次结构的任何地方找到此模型。因此,它不能仅在两个单独的步骤中进行验证和验证。此外,我实际上没有处于无效状态的必修对象,因此它应该是默认值得选择的一部分。
如果您不希望对象处于无效状态,那么我首先建议使其不变。
您可以使用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和您的其余代码库都可以用于验证。