2016-06-01 4 views
3

のリスト含まれているオブジェクトのリストをデシリアライズ:Json.Net - 私は、次の内容について説明JSONデシリアライズしようとしてるオブジェクト

型項目のオブジェクトのリストを、各項目には、いくつかのプロパティが含まれているだけでなく、自分自身の3つの特性(アクション、値、ターゲット)を含む、タイプエフェクトのオブジェクトのリスト 'レシピ'。

私は「JsonConvert.SerializeObject」を使用して私のリストをシリアル化するとき、私は、次のJSONを取得:

[ 
    { 
    "name": "WOOD", 
    "yield": 1.0, 
    "recipe": [ 
     { 
     "action": "ADD", 
     "value": 1.0, 
     "target": "WOOD" 
     } 
    ], 
    "count": 0.0, 
    "numWorkers": 0, 
    "id": 1 
    }, 
    { 
    "name": "CLAY", 
    "yield": 2.0, 
    "recipe": [ 
     { 
     "action": "ADD", 
     "value": 2.0, 
     "target": "CLAY" 
     } 
    ], 
    "count": 0.0, 
    "numWorkers": 0, 
    "id": 2 
    }, 
    { 
    "name": "SPEAR", 
    "yield": 0.5, 
    "recipe": [ 
     { 
     "action": "ADD", 
     "value": 0.5, 
     "target": "SPEAR" 
     }, 
     { 
     "action": "SUB", 
     "value": 1.0, 
     "target": "WOOD" 
     }, 
     { 
     "action": "SUB", 
     "value": 5.0, 
     "target": "CLAY" 
     } 
    ], 
    "count": 0.0, 
    "numWorkers": 0, 
    "id": 3 
    }, 
    { 
    "name": "STICK", 
    "yield": 4.0, 
    "recipe": [ 
     { 
     "action": "ADD", 
     "value": 4.0, 
     "target": "STICK" 
     }, 
     { 
     "action": "SUB", 
     "value": 1.0, 
     "target": "WOOD" 
     } 
    ], 
    "count": 0.0, 
    "numWorkers": 0, 
    "id": 4 
    } 
] 

しかし、私が使用してデシリアライズしようとすると「Items = JsonConvert.DeserializeObject<List<Item>>(jsonstring);」私はこのエラーを取得:A first chance exception of type 'System.NullReferenceException' occurred in Newtonsoft.Json.dllと私の「アイテム」リスト無効である。私は次のように取得するのC#を生成するjson2csharpを使用する場合

は:

public class Recipe 
{ 
    public string action { get; set; } 
    public double value { get; set; } 
    public string target { get; set; } 
} 

public class RootObject 
{ 
    public string name { get; set; } 
    public double yield { get; set; } 
    public List<Recipe> recipe { get; set; } 
    public double count { get; set; } 
    public int numWorkers { get; set; } 
    public int id { get; set; } 
} 

それは私の項目オブジェクトが「RootObject」で考え、それが「効果」のリストの代わりに私の「レシピ」オブジェクトを与えています

public List<Item> Items; 

private void Game_Load(object sender, EventArgs e) 
    { 
     Items = JsonConvert.DeserializeObject<List<Item>>(jsonstring); 
    } 

public class Item 
{ 
    public string name; 
    public double yield; 
    public List<Effect> recipe = new List<Effect>(); 
    public double count; 
    public int numWorkers; 
    public int id; 

    public Item() 
    { 
     name = ""; 
     //configureItem(); 
    } 

    public Item(string nm) 
    { 
     name = nm.ToUpper(); 
     //configureItem(); 
    } 

    public List<Effect> getRecipe() { 
     return recipe; 
    } 
} 

public class Effect 
{ 
    public string action; 
    public double value; 
    public string target; 

    public Effect(string act, double val, string tar) 
    { 
     action = act.ToUpper(); 
     value = val; 
     target = tar.ToUpper(); 
    } 
} 

は私がを持っている必要があります:あなたは私が働いているかを見ることができるようにリスト「レシピ」ここ

内のオブジェクトは、私のゲームやクラスのためのいくつかのコードです私のクラスのすべての変数については?私はそれを前に追加しようとしましたが、デバッグやその他の奇妙なことの間にVSがラインをスキップするように思えました。それとも、Jsonの書式設定の問題ですか?どんな助けもありがたいです、私はこのサイトとGoogleの全般を見てきました。私はここで私の髪をリッピングしています。

答えて

3

あなたEventクラスは、デフォルト(パラメータなし)コンストラクタを持っていません。ただし、パラメータ名はJSONのものと一致しません(act,valまたはtarのプロパティはありません)。この場合、Json.Netは、オブジェクトを構築するためにパラメータのデフォルト値(つまりnull)を渡し、次に戻ってフィールドを設定しようとします。問題は、あなたのコンストラクタがヌル値を扱うことができないことです。 ToUpper()を呼び出すと、acttarはnullではないとみなされます。これがNullReferenceExceptionの出所です。

一つの解決策は、(私も安全のために適切なヌルチェックを追加します)JSONに合わせて、コンストラクタのパラメータの名前を変更することです:

public Effect(string action, double value, string target) 
{ 
    this.action = (action != null ? action.ToUpper() : null); 
    this.value = value; 
    this.target = (target != null ? target.ToUpper() : null); 
} 

もう1つの可能な解決策は、プロパティにToUpperロジックを移動し、提供することですデフォルトコンストラクタ。

public class Effect 
{ 
    private string _action; 
    public string Action 
    { 
     get { return _action; } 
     set { _action = (value != null ? value.ToUpper() : null); } 
    } 

    public double Value { get; set; } 

    private string _target; 
    public string Target 
    { 
     get { return _target; } 
     set { _target = (value != null ? value.ToUpper() : null); } 
    } 

    public Effect() 
    { 
    } 
} 
+0

作成時に文字列に大文字を使用するために結んでいたので、デフォルトのコンストラクタがありません –

+0

ああ、意味があります。したがって、すべての正確な変数名を持つコンストラクタ、またはnone(パラメータなし)のコンストラクタを持つかのいずれかです。私はそれを試してみましょう。 –

+0

@ ZackF。 –

1

jsonのプロパティ名と一致するようにコンストラクタのパラメータ名を変更します。それ以外の場合、Json.netはどのフィールドがどこに属するのか把握できません。 Json.Netは、それが持つコンストラクタを使用しようとしているので、

public class Effect 
{ 
    public string action; 
    public double value; 
    public string target; 

    //public Effect(string act, double val, string tar) 
    public Effect(string action, double value, string target) 
    { 
     this.action = action.ToUpper(); 
     this.value = value; 
     this.target = target.ToUpper(); 
    } 
} 
+0

私は同じ名前を使用できますか?例えば、 'value = value'では、どの値がどのようなものかをどのように知っていますか?私は、同じ変数に代入をする警告を受けています。あなたがクラス変数名を変更した場合、Jsonはそれをシリアル化するときに別のものになるでしょう。 –

+1

@ZackFはい、コンパイラは、そのvalue = valueがthis.value = valueを意味するほど賢明です。しかし、推奨される方法として、 'this'キーワードを使用してください –

関連する問題