意想不到的Json.使用MemberSerialization时.NET异常.OptIn和required.always
本文关键字:OptIn 异常 required always NET Json 使用 MemberSerialization 意想不到 | 更新日期: 2023-09-27 18:13:23
我已经声明了一个模型类,其中一些属性将由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方法会忽略它。我是否误解了这些设置应该如何协同工作?
我觉得这是个bug。在逐步执行代码时,Json。如果将MemberSerialization
设置为OptIn
, 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; }
}
这可能是有意为之,但它似乎违反了"最小意外原则"。您可能需要报告一个问题。
作为一种解决方法,只需通过[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; }
}
您指定ItemRequired = Required.Always
,
根据文档:
获取或设置一个值,该值指示是否需要对象的属性。
你的IsInstalled
成员实际上是一个属性。
JsonObject
中的一些选项是互斥的,尽管没有明确说明。