Json.Net 自定义 ContractResolver 忽略自定义对象

Posted

技术标签:

【中文标题】Json.Net 自定义 ContractResolver 忽略自定义对象【英文标题】:Json.Net Custom ContractResolver Ignoring Custom Objects 【发布时间】:2021-10-09 02:29:03 【问题描述】:

在 Json.Net 中使用自定义 ContractResolver 时遇到一个非常奇怪的实例。

我的模型结构如下:

public class ParentClass

    public string Item1  get; set; 
    public CustomModel Item2  get; set; 


public class CustomModel

    public string CustomItem1  get; set; 
    public string CustomItem2  get; set; 


public class ChildClass : ParentClass

    public string Item3  get; set; 
    public string Item4  get; set; 

我的任务涉及创建一个仅包含 ParentClass 模型的序列化属性的 JSON 字符串,如下所示:


  "Item1": "abc",
  "Item2": 
    "CustomItem1": "def",
    "CustomItem2": "ghi"
  

因此,我创建了一个自定义合同解析器,如下所示:

public class CustomResolver : DefaultContractResolver

    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    
        return base.GetSerializableMembers(objectType).Where(member => member.DeclaringType == typeof(ParentClass) || typeof(ParentClass).IsSubclassOf(member.DeclaringType)).ToList();
    

但是当我以下列方式使用它时:

var instance = new ChildClass()

    Item1 = "abc",
    Item2 = new CustomModel()
    
        CustomItem1 = "def",
        CustomItem2 = "ghi"
    ,
    Item3 = "jkl",
    Item4 = "mno",
;

var settings = new JsonSerializerSettings

    ContractResolver = new CustomResolver(),
;
var json = JsonConvert.SerializeObject(instance, Formatting.Indented, settings);
Console.WriteLine(json);        

打印以下 JSON:


  "Item1": "abc",
  "Item2":  

演示here.

如果我不使用合约解析器,则会打印以下 JSON:


  "Item3": "jkl",
  "Item4": "mno",
  "Item1": "abc",
  "Item2": 
    "CustomItem1": "def",
    "CustomItem2": "ghi"
  

演示小提琴#2 here.

谁能解释一下这个问题?

【问题讨论】:

修复编译错误后无法reproduce。 minimal reproducible example 这里:dotnetfiddle.net/nMs9Hb。在此处修复:dotnetfiddle.net/nMs9Hb。由于一些可怜的谷歌验证码,我似乎无法发布答案。您的问题有些问题,因为您为 编写的代码但是当我以下列方式使用它时: 实际上并没有显示正在使用的合同解析器。 请检查我对您问题的编辑,看看它是否正确。我认为我已经证明了这个问题,但请确保。 @GuruStron 您无法重现它的原因是因为您没有使用自定义解析器。 @RyanFalzon 是的,没有仔细研究复制的代码) 【参考方案1】:

您的CustomResolver 可能会修复如下:

public class CustomResolver : DefaultContractResolver

    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    
        var members = base.GetSerializableMembers(objectType);
        if (objectType.IsSubclassOf(typeof(ParentClass)))
            members = members.Where(m => m.DeclaringType == typeof(ParentClass)).ToList();
        return members;
    

您的问题是 CustomModel 不是 ParentClass 的子类,因此它的属性根本不应该被过滤掉——但它们被过滤掉了,而且都被过滤掉了,因为它们不是由 ParentClass 声明的。

(我不确定您对 typeof(ParentClass).IsSubclassOf(member.DeclaringType) 的用途。ParentClass 的唯一基类是 object,它没有任何属性。)

演示小提琴here.

【讨论】:

宾果游戏!这解决了我的问题。非常感谢。

以上是关于Json.Net 自定义 ContractResolver 忽略自定义对象的主要内容,如果未能解决你的问题,请参考以下文章