A)
我有一个DLL库,包括一个类似下面的代码:
public class Thing
{
// OTHER_PROPERTIES
//..........................
[JsonProperty(Required = Required.Always)]
public bool IsBook { get; set; }
}
假设:我不访问
Thing
类的来源。
B)
我有一个像这样的JSON:
{
OTHER_PROPERTIES
}
注意: 不
的一对名称值IsBook
假设:我不会更改
JSON
以包含IsBook
。
C)
如果我运行JsonConvert.DeserializeObject<Thing>(json);
,则会收到以下错误:
错误:在json ....中找不到必需的属性。
如何通过观察问题的假设来编写自定义代码来解决上述错误? (在写完答案之前,请再次阅读上述假设。)
答案 0 :(得分:1)
您可以使用自定义合约解析程序来实现这一目标。例如:
public class Thing
{
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty(Required = Required.Always)]
public bool IsBook { get; set; }
}
class NeverRequiredContractResolver : DefaultContractResolver {
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
var prop = base.CreateProperty(member, memberSerialization);
prop.Required = Required.Default;
return prop;
}
}
然后:
var test = JsonConvert.DeserializeObject<Thing>("{\"Name\":\"some name\"}",
new JsonSerializerSettings {
ContractResolver = new NeverRequiredContractResolver()
});
当然,您可以全局分配解析器,而不是将其传递给每个DeserializeObject
:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
{
ContractResolver = new NeverRequiredContractResolver()
};
var test = JsonConvert.DeserializeObject<Thing>("{\"Name\":\"some name\"}");
你只能制作非必需的特定类的特定属性(而不是像上面的例子中的所有属性):
class CustomPropertyContractResolver : DefaultContractResolver {
private readonly Action<MemberInfo, JsonProperty> _propFixup;
public CustomPropertyContractResolver(Action<MemberInfo, JsonProperty> propFixup) {
_propFixup = propFixup;
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
var prop = base.CreateProperty(member, memberSerialization);
_propFixup?.Invoke(member , prop);
return prop;
}
}
JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
{
ContractResolver = new CustomPropertyContractResolver((member, prop) => {
if (member.DeclaringType == typeof(Thing) && member.Name == "IsBook") {
prop.Required = Required.Default;
}
})
};
var test = JsonConvert.DeserializeObject<Thing>("{\"Name\":\"some name\"}");
并根据您的具体使用情况对上述整体进行调整。