JSON.NET JsonConvert.SerializeObject()特有的行为

时间:2016-09-02 19:06:54

标签: c# json serialization json.net

这是我的情况。我们在交界处决定使用什么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提出了更全面的解决方案,所以如果你想看到它只是跟随他提供的链接作为这个问题的重复。

1 个答案:

答案 0 :(得分:4)

Json.Net不需要DataContractAttributeDataMemberAttribute。删除它们,您的代码将起作用....

要么将它们用于所有属性,要么永远不要使用它们

请参阅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()
});