使用JsonConvert进行序列化丢失数据

时间:2016-03-27 18:15:11

标签: c# json serialization json.net datacontract

我在我的项目中使用JsonConvert来从我的对象中创建一个json字符串,但是一些奇怪的事情发生了,其中一个实体在这个过程中丢失数据,这很奇怪,因为当我正在调试,实体有值,但由于某种原因,它会在此过程中丢失。

我使用JsonConvert.SerializeObject方法,这是我丢失数据的实体:

[DataContract]
public class MediaDTO : BaseEntityDTO
{
    [DataMember(IsRequired = true)]
    public int Id { get; set; }

    [DataMember(IsRequired = true)]
    public bool IsAlive { get; set; }

    [DataMember(IsRequired = true)]
    public string Description { get; set; }

    [DataMember(IsRequired = true)]
    public PidDTO Pid { get; set; }
}

[DataContract]
public class BaseEntityDTO
{ 
    [DataMember(IsRequired = true)]
    public bool IsDeleted { get; set; }

    [DataMember(IsRequired = true)]
    public DateTime AddedDate { get; set; }

    [DataMember(IsRequired = true)]
    public DateTime UpdatedDate { get; set; }
}

public class PidDTO : BaseEntityDTO
{
    public string PidId { get; set; }
    public VidDTO Vid { get; set; }
    public string Name { get; set; }
    public virtual bool IsFromUser { get; set; }
}

public VidDTO : BaseEntityDTO
{
    public virtual string VidId { get; set; }
    public virtual string Name { get; set; }
    public virtual bool IsFromUser { get; set; }
}

现在,当我查看json时,我会看到BaseEntityDTO类中的所有属性,但不会看到类本身的其他属性。

任何想法,为什么,实体或类似的东西有问题吗?

1 个答案:

答案 0 :(得分:3)

问题是您的PidDTOVidDTO类型的属性未被序列化。之所以发生这种情况,是因为其基本类型BaseEntityDTO标有[DataContract],数据合同序列化为选择加入

解决方案也是使用[DataContract]标记这些派生类型,然后使用[DataMember]标记您要序列化的所有成员:

[DataContract]
public class PidDTO : BaseEntityDTO
{
    [DataMember]
    public string PidId { get; set; }
    [DataMember]
    public VidDTO Vid { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public virtual bool IsFromUser { get; set; }
}

[DataContract]
public class VidDTO : BaseEntityDTO
{
    [DataMember]
    public virtual string VidId { get; set; }
    [DataMember]
    public virtual string Name { get; set; }
    [DataMember]
    public virtual bool IsFromUser { get; set; }
}

为什么这是否必要?从理论上讲,应用于基类DataContractAttribute的存在不应影响您的派生类型,因为DataContractAttribute sets AttributeUsageAttribute.Inherited = false

[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct|AttributeTargets.Enum, Inherited = false, 
AllowMultiple = false)]
public sealed class DataContractAttribute : Attribute

但是,Json.NET不尊重Inherited = false的{​​{1}}属性,并将数据协定类型的所有派生类型解释为具有选择性序列化,如解释here < / p>

  

[Json.NET]检测基类上的DataContractAttribute并假定选择加入序列化。

所以你需要添加这些属性。

或者,如果您只使用数据合同属性来设置IsRequired = true,则可以改为使用[JsonProperty(Required = Required.AllowNull)]代替:

DataContractAttribute

这允许派生类型继续选择退出序列化。