我已经声明了一个模型类,其中有一些属性需要由JSON填充,一些属性将由代码填充,由JsonObject和JsonProperty属性指示。这是一个简化版本:
[JsonObject(MemberSerialization.OptIn, ItemRequired = Required.Always)]
public class AppCard
{
[JsonProperty]
public string Name { get; set; }
[JsonProperty]
public string Author { get; set; }
public bool IsInstalled { get; set; }
}
以下是我单元测试中的JSON:
[
{
"name": "App 1",
"author": "Author 1"
},
{
"name": "App 2",
"author": "Author 2"
}
]
以下是我致电DeserializeObject的地方:
appCards = JsonConvert.DeserializeObject<IEnumerable<AppCard>>(content);
不幸的是,这失败并出现以下错误:
Newtonsoft.Json.JsonSerializationException: Required property 'IsInstalled'
not found in JSON. Path '[0]', line 5, position 3.
由于该属性没有JsonProperty属性并且指定了OptIn,我假设DeserializeObject方法会忽略它。我是否误解了这些设置应该如何协同工作?
答案 0 :(得分:2)
这对我来说感觉像个错误。在单步执行代码时,如果MemberSerialization
设置为OptIn
,Json.Net会将未标记的属性标记为忽略,但在检查所需属性时则不会遵循忽略的状态。如果您使用OptOut
序列化(默认值),将对象标记为具有必需属性,然后使用[JsonIgnore]
显式标记属性,则会发生同样的事情:
[JsonObject(ItemRequired = Required.Always)]
public class AppCard
{
public string Name { get; set; }
public string Author { get; set; }
[JsonIgnore]
public bool IsInstalled { get; set; }
}
这可能是设计上的,但它似乎违反了最少惊喜的原则&#34;。您可能想要report an issue。
作为一种解决方法,只需根据需要通过[JsonProperty]
属性标记各个属性,而不是在类上设置该选项。由于您已经将所有属性标记为[JsonProperty]
(通过使用OptIn
),因此使用查找和替换添加Required
选项应该很容易。
[JsonObject(MemberSerialization.OptIn)]
public class AppCard
{
[JsonProperty(Required = Required.Always)]
public string Name { get; set; }
[JsonProperty(Required = Required.Always)]
public string Author { get; set; }
public bool IsInstalled { get; set; }
}
答案 1 :(得分:0)
您指定的是ItemRequired = Required.Always
,
根据文件:
Gets or sets a value that indicates whether the object's properties are required.
您的IsInstalled
成员实际上是一个财产。
JsonObject
中的某些选项虽然not explicitly stated是互斥的。