1

この問題についてフォーラムと JSON.NET Web サイトを検索しており、ガイドラインに正しく従っていることがわかりますが、正しく機能していません。

派生クラスからオブジェクトを逆シリアル化しようとしています。シリアル化は正常に機能しますが、逆シリアル化すると、間違った型に逆シリアル化しようとします。

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 に含まれていますが、シリアル化すると無視され、もちろん別の型への逆シリアル化は失敗します。

情報を考慮に入れて正しいタイプに逆シリアル化しない理由を誰かが知っていますか?

4

1 に答える 1

1

私は犯人を見つけました:

私のプロパティの1つで、これを行っていました:

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

問題は、オブジェクトが null の場合に NoneAction を作成する getter にあります。どうやら Json.NET は、 MyClass オブジェクトの作成と MyAction オブジェクトの値の設定の間のある時点でゲッターを呼び出します。Action-property が null でないことを確認すると、オブジェクト全体を上書きする代わりに、値を割り当てようとします。

于 2013-04-07T20:02:53.413 に答える