反序列化派生类的JSON.NET无法按预期工作

时间:2013-04-07 17:54:19

标签: json windows-phone-8 json.net

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

我正在尝试从派生类反序列化对象。 序列化工作正常,但在反序列化时尝试反序列化为错误的类型。

我正在尝试使用Windows Phone 8和JSON.NET 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.NoneAction'上将值设置为'SettingsType'时出错

因此,尽管类型包含在JSON中,但在序列化时忽略它并且当然将其反序列化为其他类型失败。

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

1 个答案:

答案 0 :(得分:1)

我找到了罪魁祸首:

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

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

问题出在getter中,如果obejct为null,我会创建一个NoneAction。 显然,Json.NET在创建MyClass对象和设置MyAction对象的值之间的某个时刻调用getter。当它看到Action-property不为null时,它会尝试分配值而不是覆盖整个对象。