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; }
}
Run Code Online (Sandbox Code Playgroud)
现在,当我查看 时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; }
}
Run Code Online (Sandbox Code Playgroud)
但为什么这是必要的呢?DataContractAttribute理论上,应用于基类的存在不应影响您的派生类型,因为DataContractAttribute集合AttributeUsageAttribute.Inherited = false:
[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct|AttributeTargets.Enum, Inherited = false,
AllowMultiple = false)]
public sealed class DataContractAttribute : Attribute
Run Code Online (Sandbox Code Playgroud)
但是,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; }
}
Run Code Online (Sandbox Code Playgroud)
这允许您的派生类型继续选择退出序列化。