首页 > 解决方案 > Json.Net 自定义 ContractResolver 忽略自定义对象

问题描述

在 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": { }
}

演示在这里

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

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

演示小提琴#2在这里

任何人都可以阐明这个问题吗?

标签: c#json.net-coreserializationjson.net

解决方案


您的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;
    }
}

Your problem is that CustomModel is not a subclass of ParentClass and so its properties should not get filtered at all -- but they were, and were all filtered out, since they were not declared by ParentClass.

(I am not sure what you intended with typeof(ParentClass).IsSubclassOf(member.DeclaringType). The only base class of ParentClass is object which has no properties.)

Demo fiddle here.


推荐阅读