Json.net无法序列化派生类的属性。

23

我正在使用 JSON.NET 6.0.1 版本。当我使用 SerializeObject 方法对我的派生类对象进行序列化时,它只会序列化基类的属性。以下是代码片段:

string v = JsonConvert.SerializeObject(
                service, 
                Formatting.Indented, 
                new JsonSerializerSettings()
                {
                    TypeNameHandling = TypeNameHandling.All
                });

基础类:

[DataContract]
public abstract partial class DataEntity : IDataEntity, INotifyPropertyChanging, INotifyPropertyChanged
{
    ...
}

派生类:

[Table(Name = "dbo.mytable")]
public sealed class mytable : DataEntity
{
    ...
}

我有什么遗漏吗?

3个回答

32

是的,你忘了在派生类上添加[DataContract]属性。如果你还没有添加,你还需要给任何想要序列化的属性或字段添加[DataMember]。Json.Net在版本5.0发布1(2013年4月)中进行了更改,使得[DataContract]属性不再被继承。

请注意,如果你从你的类中删除[DataContract][DataMemeber]的所有实例,Json.Net的行为会有所不同:在这种情况下,默认行为是将基类和派生类中的所有公共属性都进行序列化处理。


有没有办法改变这种行为? - JoelFan
@JoelFan 你需要更具体一些。 - Brian Rogers
我想让JsonConvert.SerializeObject能够序列化所有属性,而不考虑任何属性。我有一个从一个标记了[DataContract]的类派生出来的类,但我的派生类没有被标记。因此,只有基类的属性被序列化。 - JoelFan
@JoelFan 请参见配置JSON.NET以忽略DataContract/DataMember属性 - Brian Rogers
1
@JoãoPortela 我已经删除了引用,因为它似乎让人们感到困惑。即使没有它,答案仍然有用。 - Brian Rogers
显示剩余3条评论

4
将属性[JsonObject(MemberSerialization.OptOut)]添加到您的派生类中,将包括所有公共成员进行序列化。
[Table(Name = "dbo.mytable")]
[JsonObject(MemberSerialization.OptOut)]
public sealed class mytable : DataEntity
{
    ...
}

或者,如果您只想序列化派生类的某些属性,您可以将属性[JsonProperty]添加到每个属性上(这相当于在每个属性上添加[DataMember]以及在类上添加[DataContract])。


太棒了@Ray,谢谢!我不明白为什么did不是被接受/最受欢迎的答案,因为网络上已经有很多评论指出TypeNameHandling.All会带来安全问题。只是顺便提一下,如果你的派生类是Internal,就像我的一样,[JsonObject(MemberSerialization.OptOut)]将无法工作。你必须在每个基类成员上使用[JsonProperty]。虽然这样做也可以! - Luis Gouveia

-2
JsonConvert.SerializeObject对我只返回了{}。我发现在序列化之前需要为该类添加一个新的构造函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接