c#-使用JsonConvert进行序列化会丢失数据
作者:互联网
这个问题已经在这里有了答案: > Json.net serialize/deserialize derived types? 3个
我在项目中使用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类的所有属性,但看不到该类本身的其他属性.
知道为什么,实体或类似的东西有问题吗?
解决方法:
问题是您的PidDTO和VidDTO类型的属性没有被序列化.发生这种情况是因为其基本类型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不遵守DataContractAttribute的Inherited = false属性,而是将数据协定类型的所有派生类型解释为具有选择加入序列化,如here所述
[Json.NET] detects the DataContractAttribute on the base class and assumes opt-in serialization.
因此,您毕竟需要添加这些属性.
或者,如果仅使用数据协定属性来设置IsRequired = true
,则可以改为使用[JsonProperty(Required = Required.AllowNull)]
:
public class MediaDTO : BaseEntityDTO
{
[JsonProperty(Required = Required.AllowNull)]
public int Id { get; set; }
[JsonProperty(Required = Required.AllowNull)]
public bool IsAlive { get; set; }
[JsonProperty(Required = Required.AllowNull)]
public string Description { get; set; }
[JsonProperty(Required = Required.AllowNull)]
public PidDTO Pid { get; set; }
}
public class BaseEntityDTO
{
[JsonProperty(Required = Required.AllowNull)]
public bool IsDeleted { get; set; }
[JsonProperty(Required = Required.AllowNull)]
public DateTime AddedDate { get; set; }
[JsonProperty(Required = Required.AllowNull)]
public DateTime UpdatedDate { get; set; }
}
这使您的派生类型可以继续选择退出序列化.
标签:datacontract,serialization,json-net,json,c 来源: https://codeday.me/bug/20191118/2031575.html