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

标签 c# json list json.net deserialization

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

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

当我使用“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我的“项目”列表为空。

当我使用 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; } 吗?对于我类(class)中的所有变量?我之前尝试添加它,但它似乎导致我的 VS 在调试期间跳过行以及各种其他怪异现象。或者它只是一个 Json 格式问题?任何帮助将不胜感激,我已经查看了整个网站和整个 Google,我正在这里扯掉我的头发。

最佳答案

您的 Event 类没有默认(无参数)构造函数,因此 Json.Net 正在尝试使用它拥有的构造函数。但是,参数名称与 JSON 中的任何内容都不匹配(不存在 actvaltar 属性)。在这种情况下,Json.Net 将为参数传递默认值(即 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()
    {
    }
}

关于c# - Json.Net - 反序列化包含对象列表的对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37571690/

相关文章:

json - 连接停止时如何处理 mongoose 数据库

c# - 派生类列表上的泛型函数

html - 使 html 列表适合父元素高度

c# - 对象引用未设置为 C# winform devexpress 中对象错误的实例?

c# - WPF 网格不同的列大小和位置

c# - 我应该使用哪个,CodeContract 还是 CuttingEdge.Conditions?

ruby-on-rails - 通过 JSON/XML 将二进制数据发送到 (Rails) RESTful 端点?

c# - 如何设置 nuget 引用的动态路径?

javascript - 如何从restful web服务访问json对象的属性

python - 元音列表 : weird lambda expression