当Json.NET遇到一个没有无参数构造函数但有参数构造函数的对象时,它会调用该构造函数来创建该对象,使用反射按名称将 JSON 属性名称与构造函数参数进行匹配 http://www.newtonsoft.com/json/help/html/JsonConstructorAttribute.htm通过不区分大小写的最佳匹配算法。 IE。名称也出现在构造函数中的属性将通过构造函数调用进行设置,而不是通过 set 方法(即使有)。
因此,您可以通过将等效属性标记为所需的来标记构造函数参数required http://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_JsonPropertyAttribute_Required.htm:
public class Dog
{
public Dog(int age)
{
this.Age = age;
}
[JsonProperty(Required = Required.Always)]
public int Age { get; }
}
Now JsonConvert.DeserializeObject<Dog>(jsonString)
当"age"
财产丢失。
既然这是你的事always想要,你可以创建一个自定义合约解析器 http://www.newtonsoft.com/json/help/html/contractresolver.htm继承自DefaultContractResolver http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_DefaultContractResolver.htm or CamelCasePropertyNamesContractResolver http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_CamelCasePropertyNamesContractResolver.htm它将自动将传递给构造函数的属性标记为必需,而不需要属性:
public class ConstructorParametersRequiredContractResolver : DefaultContractResolver
{
protected override JsonProperty CreatePropertyFromConstructorParameter(JsonProperty matchingMemberProperty, ParameterInfo parameterInfo)
{
var property = base.CreatePropertyFromConstructorParameter(matchingMemberProperty, parameterInfo);
if (property != null && matchingMemberProperty != null)
{
var required = matchingMemberProperty.Required;
// If the member is already explicitly marked with some Required attribute, don't override it.
// In Json.NET 12.0.2 and later you can use matchingMemberProperty.IsRequiredSpecified to check to see if Required is explicitly specified.
// if (!matchingMemberProperty.IsRequiredSpecified)
if (required == Required.Default)
{
if (matchingMemberProperty.PropertyType != null && (matchingMemberProperty.PropertyType.IsValueType && Nullable.GetUnderlyingType(matchingMemberProperty.PropertyType) == null))
{
required = Required.Always;
}
else
{
required = Required.AllowNull;
}
// It turns out to be necessary to mark the original matchingMemberProperty as required.
property.Required = matchingMemberProperty.Required = required;
}
}
return property;
}
}
然后构造解析器的实例:
static IContractResolver requiredResolver = new ConstructorParametersRequiredContractResolver();
并按如下方式使用它:
var settings = new JsonSerializerSettings { ContractResolver = requiredResolver };
JsonConvert.DeserializeObject<T>(jsonString, settings)
现在反序列化将会抛出,如果"age"
JSON 中缺少属性。
Notes:
演示小提琴here https://dotnetfiddle.net/KaLsil.