Json.Net-反序列化包含对象列表的对象列表



我正在尝试反序列化描述以下内容的json:

Item类型的对象列表,每个Item都包含一些属性,以及Effect类型的对象的列表"配方",其中包含三个自己的属性(动作、值和目标)。

当我使用"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和我的"Items"列表为null。

当我使用json2csharp生成c#时,我得到以下内容:

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; }
}

它认为我的Item对象是"RootObject",它给了我一个"Recipe"对象,而不是列表"Recipe"中的"Effect"对象列表

下面是我的游戏和类的一些代码,这样你就可以看到我在使用什么:

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();
}
}

我的类中的所有变量都需要{ get; set; }吗?我之前尝试过添加,但这似乎导致我的VS在调试过程中跳过行,以及其他各种奇怪的事情。还是只是Json格式问题?如果有任何帮助,我都会不胜感激,我已经浏览了这个网站和谷歌,我在这里简直是疯了。

您的Event类没有默认(无参数)构造函数,因此Json.Net正在尝试使用它拥有的构造函数。但是,参数名称与JSON中的任何内容都不匹配(不存在actvaltar属性)。在这种情况下,Json.Net将传递参数的默认值(即null),以便构造对象,然后返回并尝试设置字段。问题是您的构造函数没有被配置为处理null值。它假设acttar在调用ToUpper()时不会为空。这就是NullReferenceException的来源。

一个解决方案是重命名构造函数参数以匹配JSON(为了安全起见,我还会添加适当的null检查):

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);
}

另一种可能的解决方案是将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()
{
}
}

重命名构造函数的参数名称以匹配json中的属性名称,否则它是不明确的,因此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();
}
}

相关内容

  • 没有找到相关文章

最新更新