这是我的情况。我们在交界处决定使用什么Json序列化工具。我们正在考虑使用Newtonsoft.JSON和Microsoft JavaScriptSerializer。 Newtonsoft.JSON是我们第一次看到,但我们偶然发现了一些特殊的行为。这是说明问题的示意代码。 假设我们有以下类的处置:
interface IA<T>
{
T Id { get; set; }
}
[DataContractAttribute]
abstract class A : IA<string>
{
protected A() { }
[DataMemberAttribute]
public virtual string Id
{
get;
set;
}
}
class B : A
{
public string P1 { get; set; }
public string P2 { get; set; }
}
然后,如果我们将利用Newtonsoft.Json的JsonConvert类从B类中获取JSON字符串,我们可以使用以下代码:
B b = new B();
string jsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(b,
new Newtonsoft.Json.JsonSerializerSettings() {
NullValueHandling = Newtonsoft.Json.NullValueHandling.Include
});
但遗憾的是,只有Id属性会反映在生成的JSON字符串中。 B类的所有其他属性都不会显示出来。相反,JavaScriptSerializer会按预期生成JSON字符串。 B类是我们的类,A类和接口IA来自第三方库,所以我们无法修改它们。此外,我们不希望在我们的类上使用数据协定序列化注释,只是为了安抚挑剔的json序列化程序。
有没有办法指示Newtonsoft.Json.JsonConvert序列化所有属性,无论是否注释?
编辑:虽然@LB提供了可接受的答案@dbc提出了更全面的解决方案,所以如果你想看到它只是跟随他提供的链接作为这个问题的重复。
答案 0 :(得分:4)
Json.Net不需要DataContractAttribute
和DataMemberAttribute
。删除它们,您的代码将起作用....
要么将它们用于所有属性,要么永远不要使用它们
请参阅http://www.newtonsoft.com/json/help/html/DataContractAndDataMember.htm
------编辑-------
如果您不想使用任何Attributes
,那么您可以创建自定义ContractResolver
public class MyDefaultContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var result = base.CreateProperties(type, memberSerialization).ToList();
result.ForEach(x => { x.Ignored = false; }); // <-- Include or not?
return result;
}
}
将您的代码序列化为:
string jsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(b,
new Newtonsoft.Json.JsonSerializerSettings()
{
NullValueHandling = Newtonsoft.Json.NullValueHandling.Include,
ContractResolver = new MyDefaultContractResolver()
});