如果希望在Number
为10时强制Text
存在且不为空,并且需要纯Newtonsoft解决方案,则可以在参数化构造函数中执行此操作:
public class Foo
{
[JsonConstructor]
// Make public if you want to enforce the same requirements during regular construction
protected Foo(int number, string text)
{
if (number > 10 && text == null)
throw new ArgumentException("missing text");
this.Number = number;
this.Text = text;
}
// Remove if you want to enforce the same requirements during regular construction
public Foo() { }
[JsonProperty(Required = Required.Always)]
public int Number { get; set; }
public string Text { get; set; }
}
请注意,构造函数参数的名称必须与相应的属性相同,忽略大小写的差异.
here.第一次见面
或者,如果出于某种原因不喜欢使用构造函数,可以在[OnDeserialized]
回调中进行判断:
public class Foo
{
[JsonProperty(Required = Required.Always)]
public int Number { get; set; }
public string Text { get; set; }
[System.Runtime.Serialization.OnDeserialized]
void OnDeserializedMethod(System.Runtime.Serialization.StreamingContext context)
{
if (Number > 10 && Text == null)
{
throw new JsonSerializationException("missing text");
}
}
}
here.第一次见面
请注意,两种解决方案都将null
的值与Text
等同于缺失值. 如果你想让{"Number":20, "Text":null}
有效,你需要采用一个更复杂的解决方案,比如记住Text
是否曾经被设置过,并在[OnDeserialized]
回调中判断它:
public class Foo
{
[JsonProperty(Required = Required.Always)]
public int Number { get; set; }
string text;
bool textSpecified;
public string Text { get => text; set { text = value; textSpecified = true; } }
[System.Runtime.Serialization.OnDeserialized]
void OnDeserializedMethod(System.Runtime.Serialization.StreamingContext context)
{
if (Number > 10 && !textSpecified)
{
throw new JsonSerializationException("missing text");
}
}
}
演示小提琴#3 here.