在调用DeserializeObject<Object>(...)时验证Json数据

3

我希望在反序列化Json代码之后进行验证。
例如,如果我有...

using Newtonsoft.Json;
...
public Car
{
  public int Year{ get; set; }
  public String Make{ get; set; }
}
...
JsonConvert.DeserializeObject<Car>(json)

我想验证年份是否为< 2017 && >=1900,例如。
或者确保Make是非空字符串(或者它是可接受的值)。
我知道我可以在反序列化后添加Validate()类型函数,但我很好奇是否有一种方法可以同时执行JsonConvert.DeserializeObject<Car>(json)
2个回答

3

也许这个工作最合适的工具是一个序列化回调

只需创建一个Validate方法并在其上添加一个[OnDeserialized]属性:

public Car
{
  public int Year{ get; set; }
  public String Make{ get; set; }

  [OnDeserialized]
  internal void OnDeserializedMethod(StreamingContext context)
  {
    if (Year > 2017 || Year < 1900)
      throw new InvalidOperationException("...or something else");
  }
}

2

使用设置器将其插入。

public class Car
{
    private int _year;

    public int Year
    {
        get { return _year; }
        set
        {
            if (_year > 2017 || _year < 1900)
                throw new Exception("Illegal year");
            _year = value;
        }
    }
}

对于整个对象的验证,只需在设置任何值时进行验证。

public class Car
{
    private int _year;
    private string _make;

    public string Make 
    {
        get { return _make; }
        set
        {
            _make = value;
            ValidateIfAllValuesSet();
        }
    }

    public int Year
    {
        get { return _year; }
        set
        {
            _year = value;
            ValidateIfAllValuesSet();
        }
    }

    private void ValidateIfAllValuesSet()
    {
        if (_year == default(int) || _make == default(string))
            return;

        if (_year > 2017 || _year < 1900)
            throw new Exception("Illegal year");
    }
}

谢谢,但如果两个值是相关的,例如,如果“年份”范围取决于“制造商”或类似情况。我几乎必须等待所有值都设置好了。 - FFMG
然后编写一个单一的 setter,如果提供了所有数据,则调用验证函数。 - Silas Reinagel
我更倾向于使用可以在汽车完全构建后用于验证的“DataAnnotations”,或者只是一个名为“ValidateCar”的方法,可以运行您需要执行的任何逻辑以进行反序列化后的操作。让您的设置器运行逻辑可能会很快变得混乱。 - Jonesopolis
我完全同意。这是最简单的解决方案,不需要花哨的东西,但一旦你开始使用最终一致性和最终验证,它就变得很丑陋。只需在反序列化后调用obj.Validate()更加清晰简洁。 - Silas Reinagel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接