A)
我有一个 DLL 库,其中包含一个类,如下所示:
public class Thing
{
// OTHER_PROPERTIES
//..........................
[JsonProperty(Required = Required.Always)]
public bool IsBook { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
假设:我无法访问该类的源代码
Thing。
二)
我有一个像这样的 JSON:
{
OTHER_PROPERTIES
}
Run Code Online (Sandbox Code Playgroud)
注意:它没有一对名称/值
IsBook假设:我不会更改
JSON包含IsBook在其中的内容。
C)
如果我运行,JsonConvert.DeserializeObject<Thing>(json);则会出现以下错误:
错误:在 json 中找不到所需的属性 ....
如何通过观察问题的假设来编写自定义代码来解决上述错误?(在写下你的答案之前,请再次阅读上述假设。)
您可以使用自定义合同解析器来实现这一点。例如:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
进而:
var test = JsonConvert.DeserializeObject<Thing>("{\"Name\":\"some name\"}",
new JsonSerializerSettings {
ContractResolver = new NeverRequiredContractResolver()
});
Run Code Online (Sandbox Code Playgroud)
当然,您可以全局分配解析器而不是将其传递给每个DeserializeObject:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
{
ContractResolver = new NeverRequiredContractResolver()
};
var test = JsonConvert.DeserializeObject<Thing>("{\"Name\":\"some name\"}");
Run Code Online (Sandbox Code Playgroud)
您可以仅将特定类的特定属性设为非必需(而不是像上面的示例中那样全部):
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\"}");
Run Code Online (Sandbox Code Playgroud)
以及上面的整体调整示例,但是您希望适合您的特定用例。
| 归档时间: |
|
| 查看次数: |
6932 次 |
| 最近记录: |