JSON.Net 中的业务验证

考虑我们有一个类型描述参与 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 中表达它?外部方法不太适合,因为此模型可能会在多个层次结构的任何地方找到。因此,它不能仅在两个单独的步骤中进行反序列化和验证。此外,我实际上并没有可能处于无效状态的反序列化对象,因此它应该是默认反序列化的一部分。


MYYA
浏览 94回答 1
1回答

慕运维8079593

如果您不希望对象处于可能无效的状态,那么我首先建议将其设为不可变。然后,您可以使用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 和您的代码库的其余部分都可以用于验证。
打开App,查看更多内容
随时随地看视频慕课网APP