反序列化从 Json 继承的 ReactiveObject 的对象不起作用

Posted

技术标签:

【中文标题】反序列化从 Json 继承的 ReactiveObject 的对象不起作用【英文标题】:Deserializing object that inherits from ReactiveObject from Json does not work 【发布时间】:2018-12-12 04:49:04 【问题描述】:

我正在尝试将一些 json 反序列化为一些从 Reactive UI 的 ReactiveObject 类继承的简单对象。由于某种原因,那里的房产永远不会被填满。使用 POCO 可以正常工作。

class Program

    class Profile
    
        public string Name  get; set; 
    

    class ReactiveProfile : ReactiveObject
    
        private string _name;

        public string Name
        
            get => _name;
            set => this.RaiseAndSetIfChanged(ref _name, value);
        
    

    static void Main(string[] args)
    
        var profiles = new List<Profile>()
        
            new Profile() Name = "Foo",
            new Profile() Name = "Bar"
        ;

        var path = @"C:\temp\profiles.json";

        File.WriteAllText(path,
            JsonConvert.SerializeObject(profiles.ToArray(),
                Formatting.Indented,
                new StringEnumConverter()),
            Encoding.UTF8);

        // works
        var pocoProfiles = (Profile[])JsonConvert.DeserializeObject(
            File.ReadAllText(path, Encoding.UTF8),
            typeof(Profile[]));

        // properties not filled
        var reactiveProfiles = (ReactiveProfile[])JsonConvert.DeserializeObject(
            File.ReadAllText(path, Encoding.UTF8),
            typeof(ReactiveProfile[]));

        if (File.Exists(path))
        
            File.Delete(path);
        
    

【问题讨论】:

【参考方案1】:

要正确序列化 ReactiveObjects,您应该使用 System.Runtime.Serialization 命名空间的 DataContract 属性。然后用 DataMember 属性标记你想保存的成员,用 IgnoreDataMember 属性标记你不想保存的成员。

所以在你的情况下,是这样的:

[DataContract]
class ReactiveProfile : ReactiveObject

    [IgnoreDataMember]
    private string _name;

    [DataMember]
    public string Name
    
        get => _name;
        set => this.RaiseAndSetIfChanged(ref _name, value);
    

这是 Paul 在 Github 上的旧示例用法之一:link

还有一个数据持久化的文档链接:link

我运行了您随此更改提供的代码,它按预期工作。如果您有任何问题,请告诉我。

【讨论】:

完美运行!你能解释一下为什么我必须明确地这样做吗?因为当我将 Poco Profile 类上的 Name 属性更改为使用支持字段时,它仍然可以在没有属性的情况下在那里工作。 @metacircle 简而言之,这是因为 ReactiveObject 具有 DataContract 属性。因此,派生类中任何未用 DataMember 属性修饰的属性都不会被序列化(至少使用 JSON.net;其他序列化库可能没有这种副作用)。查看this answer 了解更多信息。如果您对这些属性感到好奇,请查看nice, quick overview。

以上是关于反序列化从 Json 继承的 ReactiveObject 的对象不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Newtonsoft.json 序列化和反序列化基/继承,其中类来自共享项目

Python继承模式 - 如何处理反序列化

从 JSON 反序列化 java 枚举

从 JSON 反序列化重复字典

json 从遗留属性名称反序列化

从xml继承/实现List/ICollection/e.t.c反序列化类型