Json.Net 自定义 ContractResolver 忽略自定义对象
Json.Net Custom ContractResolver Ignoring Custom Objects
在 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; }
}
我的任务涉及创建一个 JSON 字符串,它仅包含 ParentClass 模型的序列化属性,如下所示:
{
"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"
}
}
演示 fiddle #2 here.
任何人都可以阐明这个问题吗?
您的 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
的子 class,因此它的属性根本不应该被过滤掉——但它们被过滤掉了,而且都被过滤掉了, 因为它们不是由 ParentClass
.
声明的
(我不确定您对 typeof(ParentClass).IsSubclassOf(member.DeclaringType)
的意图。ParentClass
的唯一基础 class 是没有属性的 object
。)
演示 fiddle here.
在 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; }
}
我的任务涉及创建一个 JSON 字符串,它仅包含 ParentClass 模型的序列化属性,如下所示:
{
"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"
}
}
演示 fiddle #2 here.
任何人都可以阐明这个问题吗?
您的 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
的子 class,因此它的属性根本不应该被过滤掉——但它们被过滤掉了,而且都被过滤掉了, 因为它们不是由 ParentClass
.
(我不确定您对 typeof(ParentClass).IsSubclassOf(member.DeclaringType)
的意图。ParentClass
的唯一基础 class 是没有属性的 object
。)
演示 fiddle here.