【问题标题】:Json.Net Custom ContractResolver Ignoring Custom ObjectsJson.Net 自定义 ContractResolver 忽略自定义对象
【发布时间】: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 是的,没有仔细研究复制的代码)

标签: c# json .net-core serialization json.net


【解决方案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.

【讨论】:

  • 宾果游戏!这解决了我的问题。非常感谢。
猜你喜欢
  • 2014-10-09
  • 1970-01-01
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 2011-09-18
  • 2019-09-23
  • 2010-09-10
  • 1970-01-01
相关资源
最近更新 更多