JSON.NET反序列化派生类不能按预期工作



我一直在搜索论坛和JSON。. NET网站在这个问题上,从我可以看到我正确地遵循指导方针,但它不能正常工作。

我试图从派生类反序列化对象。序列化工作正常,但是当反序列化时,它试图反序列化到错误的类型。

我正试图用Windows Phone 8和JSON做这件事。净4.5.11

我有以下我正在序列化的类:

public class MyClass : ModelBase
{
    public string Title { get; set; }
    [JsonProperty(TypeNameHandling = TypeNameHandling.All)]
    public MyAction Action {get; set; }
}

public abstract class MyAction : ModelBase
{
    [JsonIgnore()]
    public abstract ActionType ActionType { get; }
    public abstract void Execute();
}
public class SettingsAction : MyAction 
{
    public override ActionType ActionType
    {
        get { return ActionType.Settings; }
    }
    public SettingsType SettingsType {get; set; }
    public override void Execute()
    {
    }
}
public class NoneAction : MyAction 
{
    public override ActionType ActionType
    {
        get { return ActionType.None; }
    }
    public override void Execute()
    {
        return;
    }
}

我像这样序列化它:

MyClass obj = new MyClass 
{
    Action = new SettingsAction()
};
string json = JsonConvert.SerializeObject(
                obj, 
                Formatting.Indented, 
                new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });
using (StreamWriter writer = new StreamWriter(stream))
{
    writer.Write(json);
}

它给了我以下JSON:

{
  "$type": "Model.MyClass, Model",
  "Title": null,
  "Action": {
    "$type": "Model.SettingsAction, Model",
    "SettingsType": 0
  }
}

在我看来,这是正确的,我告诉它包含类型信息,它正确地包含了

我这样反序列化:

using (StreamReader r = new StreamReader(stream))
{
    string json = r.ReadToEnd();
    MyClass obj = JsonConvert.DeserializeObject<MyClass>(json);
}

我得到以下错误:

JsonSerializationException:在'Model '上设置值为'SettingsType'时出错。NoneAction"

因此,尽管JSON中包含该类型,但在序列化时它会忽略它,当然反序列化为不同的类型会失败。

有人知道为什么它不考虑信息并反序列化为正确的类型吗?

我找到了罪魁祸首:

在我的一个属性中,我这样做了:

public MyAction Action
{
    get 
    {
        if (_Action == null) {
            Action = new NoneAction();
        }
        return _Action; 
    }
    set
    {
        if (value != _Action)
        {
            _Action = value;
            NotifyPropertyChanged("Action");
        }
    }
}

问题是在getter中,如果对象为空,我将创建一个NoneAction。显然Json。. NET在创建MyClass对象和设置MyAction对象的值之间的某个时刻调用getter。当它看到action属性不为空时,它会尝试赋值,而不是覆盖整个对象。

最新更新