Pac*_*chu 5 c# serialization json datacontract json.net
我在我的项目中使用它是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],并且数据协定序列化是opt-in。  
解决方案还包括使用 标记这些派生类型[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集合AttributeUsageAttribute.Inherited = false:
[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct|AttributeTargets.Enum, Inherited = false, 
AllowMultiple = false)]
public sealed class DataContractAttribute : Attribute
但是,Json.NET 不尊重数据协定类型Inherited = false的属性DataContractAttribute,并将数据协定类型的所有派生类型解释为具有选择加入序列化,如此处所述
[Json.NET] 检测基类上的 DataContractAttribute 并假定选择加入序列化。
所以你毕竟需要添加这些属性。
或者,如果您仅使用数据协定属性来设置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; }
}
这允许您的派生类型继续选择退出序列化。