我试图反序列化描述以下内容的json:
Item类型的对象列表,每个Item包含一些属性以及列表' recipe' Effect类型的对象包含它们自己的三个属性(action,value和target)。
当我使用' 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
}
]
但是当我尝试使用&#39; Items = JsonConvert.DeserializeObject<List<Item>>(jsonstring);
&#39;进行反序列化时我收到此错误:A first chance exception of type 'System.NullReferenceException' occurred in Newtonsoft.Json.dll
和我的&#39;项目&#39;列表为空。
当我使用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对象是&#39; RootObject&#39;并且它给了我一份食谱&#39;对象而不是效果列表&#39;列表中的对象&#39;配方&#39;
这里有我的游戏和课程的一些代码,以便您可以看到我正在使用的内容:
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格式问题?任何帮助将不胜感激,我已经遍布这个网站和谷歌一般,我在这里撕开我的头发。
答案 0 :(得分:3)
您的Event
类没有默认(无参数)构造函数,因此Json.Net正在尝试使用它具有的构造函数。但是,参数名称与JSON中的任何内容都不匹配(不存在act
,val
或tar
属性。在这种情况下,Json.Net将为参数传递默认值(即null
)以获取构造的对象,然后返回并尝试设置字段。问题是你的构造函数没有配备处理null值。它假定act
和tar
在调用ToUpper()
时不会为空。这是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);
}
另一种可能的解决方案是将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()
{
}
}
答案 1 :(得分:1)
重命名构造函数的参数名称以匹配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();
}
}