Newtonsoft序列化隐藏的继承成员

时间:2018-08-21 21:12:34

标签: json uwp

在具有类继承的UWP项目中使用Newtonsoft.Json 11.0.2,我们希望能够序列化父类而不序列化基类,并且我们还希望能够序列化其他调用中的基类属性。我们将该问题重新应用于示例...

[DataContract]
public class Object1
{
    [DataMember]
    public string Property1
    {
        get { return "Property 1 data"; }
    }

    [DataMember]
    public string Property2
    {
        get { return "Property 2 data"; }
    }

    [DataMember]
    public string Property3
    {
        get { return "Property 3 data"; }
    }

}

[DataContract]
public class Object2 : Object1
{
    [DataMember]
    public string Property4
    {
        get { return "Property 4 data"; }
    }

    [DataMember]
    public string Property5
    {
        get { return "Property 5 data"; }
    }

    [DataMember]
    public string Property6
    {
        get { return "Property 6 data"; }
    }

    [IgnoreDataMember]
    public new string Property2
    {
        get { return "Property 2 data"; }
    }
}

序列化对象...

Object2 myobject = new Object2();

string serialized = JsonConvert.SerializeObject(myobject);

结果...

{“ Property4”:“ Property 4数据”,“ Property5”:“ Property 5数据”,“ Property6”:“ Property 6数据”,“ Property2”:“ Property 2数据”,“ Property1”:“ Property 1 data“,” Property3“:” Property 3 data“}

属性2被序列化,即使其设置为隐藏和/或忽略。

我希望序列化Object2不会显示Property2,因为它是使用new关键字“隐藏”的,并且未使用DataMember设置和/或专门忽略的。

2 个答案:

答案 0 :(得分:0)

  

删除它或使其私有化并不能解决问题,因为我们确实希望能够使用该属性序列化基类。

如果您不想序列化object2中的Property2,但仍想序列化object1中的Property2。您的原始代码应该可以工作。我相信您应该为Property2的相同值感到困惑。您只需更改object2中Property2的值即可。

[DataContract]
public class Object2 : Object1
{
    [DataMember]
    public string Property4
    {
        get { return "Property 4 data"; }
    }

    [DataMember]
    public string Property5
    {
        get { return "Property 5 data"; }
    }

    [DataMember]
    public string Property6
    {
        get { return "Property 6 data"; }
    }

    [IgnoreDataMember]
    public new string Property2
    {
        get { return "new Property 2 data"; }
    }
}
Object2 myobject = new Object2();
string serialized = JsonConvert.SerializeObject(myobject);

结果:{"Property4":"Property 4 data","Property5":"Property 5 data","Property6":"Property 6 data","Property2":"Property 2 data","Property1":"Property 1 data","Property3":"Property 3 data"}

您会看到它只是序列化了object1中的Property2

答案 1 :(得分:0)

感谢XavierXie-MSFT指出我无法分辨哪个对象正在序列化,因为两个对象中的数据相同。如我所料,原始示例将从基类序列化属性。这不是一个答案,只能更清楚地说明我的观点,但这确实有助于我进一步分析。

为了获得所需的行为,我必须将基类Property2设为虚拟,并覆盖父类中的属性。在这种情况下,Property2仍从父类进行序列化。然后我更改为使用newtonsoft序列化忽略[JasonIgnore]。然后,当实例化为Object2类型时,Property2不再从任何一个类进行序列化。

我希望躲在new上也能得到相同的结果。

我希望[IgnoreDataMember]会像[JsonIgnore]那样忽略掉被覆盖的Property2。

如果在父类的Property2上没有标签,那么我会期望重写的Property2不会序列化。

幸运的是,虚拟化和[JsonIgnore]都能正常工作。

解决方案:

[DataContract]
public class Object1
{
    public Object1()
    {
        Property1 = "property 1 data from object 1";
        Property2 = "property 2 data from object 1";
        Property3 = "property 3 data from object 1";
        Property0 = "should not be serialized from object 1";
    }

    public string Property0
    {
        get;
        set;
    }

    [DataMember]
    public string Property1
    {
        get;
        set;
    }

    [DataMember]
    public virtual string Property2
    {
        get;
        set;
    }

    [DataMember]
    public string Property3
    {
        get;
        set;
    }

}

[DataContract]
public class Object2 : Object1
{
    public Object2()
    {
        Property4 = "property 4 data from object 2";
        Property5 = "property 5 data from object 2";
        Property6 = "property 6 data from object 2";
        Property2 = "should not be serialized from object 2";
        Property7 = "should not be serialized from object 2";
    }

    [DataMember]
    public string Property4
    {
        get;
        set;
    }

    [DataMember]
    public string Property5
    {
        get;
        set;
    }

    [DataMember]
    public string Property6
    {
        get;
        set;
    }


    /// <summary>
    /// from parent class
    /// </summary>
    [JsonIgnore]
    public override string Property2
    {
        get;
        set;
    }

    public string Property7
    {
        get;
        set;
    }

}

Object2 myobject = new Object2();

string serialized = JsonConvert.SerializeObject(myobject);

Object1 mybaseobject = new Object1();

string baseserialized = JsonConvert.SerializeObject(mybaseobject);

结果:

序列化 {“ Property4”:“来自对象2的属性4数据”,“ Property5”:“来自对象2的属性5数据”,“ Property6”:“来自对象2的属性6数据”,“ Property1”:“来自对象的属性1数据1“,” Property3“:”来自对象1的属性3数据“}

baseserialized {“ Property1”:“来自对象1的属性1数据”,“ Property2”:“来自对象1的属性2数据”,“ Property3”:“来自对象1的属性3数据”}

注意:即使使用[IgnoreDataMember],C#UWP DataContractSerializer仍将从父类序列化Property2。