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

met*_*cle 3 c# json.net reactiveui

我正在尝试将一些 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Col*_*man 5

要正确序列化 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

以及数据持久性的文档链接:链接

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

  • 简而言之,@metacircle,这是因为 ReactiveObject 具有 _DataContract_ 属性。因此,派生类中未用 _DataMember_ 属性修饰的任何属性都不会被序列化(至少使用 JSON.net;其他序列化库可能不会有这种副作用)。查看[此答案](/sf/answers/2044271351/)以获取更多信息。如果您对这些属性感到好奇,这里有一个[很好、快速的概述](/sf/answers/338576241/)。 (3认同)