【问题标题】:Deserialize JSON to List in C# in a console application在控制台应用程序中将 JSON 反序列化为 C# 中的列表
【发布时间】:2020-02-17 17:07:17
【问题描述】:

错误

无法反序列化当前 JSON 对象(例如 {"name":"value"}) 进入类型'System.Collections.Generic.List`1 [ConsoleApp1.Menu]' 因为该类型需要一个 JSON 数组(例如 [1,2,3])来反序列化 正确。要修复此错误,请将 JSON 更改为 JSON 数组 (例如 [1,2,3])或更改反序列化类型,使其成为正常的 .NET 类型(例如,不是像整数这样的原始类型,也不是集合 可以从 JSON 反序列化的数组或列表等类型 目的。 JsonObjectAttribute 也可以添加到类型中来强制它 从 JSON 对象反序列化。路径“测试”,第 3 行,位置 9。

问题

为什么会出现这个错误?

最后我想实现在控制台中编写每个菜单项。现在我被这个错误困住了。我如何获得这样的结果(输出):

ID: 1 Name: Frosted Pumpkin Bread
ID: 2 Name: Ground to Go
...

控制台应用程序

using System;
using System.Collections.Generic;
using System.Net;
using Newtonsoft.Json;


namespace ConsoleApp1
{
    public class MenuItem
    {
        public string ID { get; set; }
        public string Description { get; set; }
        public string Summary { get; set; }
        public string Name { get; set; }
        public string ImageFile { get; set; }
    }

    public class Menu
    {
        public List<MenuItem> Test { get; set; }
    }


    class Program
    {

        static void Main(string[] args)
        {
          var webclient = new WebClient();
          var json = webclient.DownloadString(@"C:\Users\devuser\source\repos\ConsoleApp1\ConsoleApp1\data.json");
          var model = JsonConvert.DeserializeObject<List<Menu>>(json);

            foreach (var item in model)
            {
                Console.WriteLine();
            }
        }
    }
}

我的 JSON 文件如下所示


{

  "Test": [

    {
      "ID": "1",
      "Description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, tenetur natus doloremque laborum quos iste ipsum rerum obcaecati impedit odit illo dolorum ab tempora nihil dicta earum fugiat. Temporibus, voluptatibus. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, tenetur natus doloremque laborum quos iste ipsum rerum obcaecati impedit odit illo dolorum ab tempora nihil dicta earum fugiat. Temporibus, voluptatibus.",
      "Summary": "A seasonal delight we offer every autumn.  Pumpking bread with just a bit of spice, cream cheese frosting with just a hint of home.",
      "Name": "Frosted Pumpkin Bread",
      "ImageFile": "pumpkinbread.png"
    },
    {
      "ID": "2",
      "Description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, tenetur natus doloremque laborum quos iste ipsum rerum obcaecati impedit odit illo dolorum ab tempora nihil dicta earum fugiat. Temporibus, voluptatibus. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, tenetur natus doloremque laborum quos iste ipsum rerum obcaecati impedit odit illo dolorum ab tempora nihil dicta earum fugiat. Temporibus, voluptatibus.",
      "Summary": "Love our coffee? Take it with you so you never have to be without!",
      "Name": "Ground to Go",
      "ImageFile": "granola.png"
    },
    {
      "ID": "3",
      "Description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, tenetur natus doloremque laborum quos iste ipsum rerum obcaecati impedit odit illo dolorum ab tempora nihil dicta earum fugiat. Temporibus, voluptatibus. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, tenetur natus doloremque laborum quos iste ipsum rerum obcaecati impedit odit illo dolorum ab tempora nihil dicta earum fugiat. Temporibus, voluptatibus.",
      "Summary": "Do you prefer to grind your own coffee? No problem, we'll give you the beans.",
      "Name": "Bean there, done that!",
      "ImageFile": "beans.jpg"
    },
    {
      "ID": "4",
      "Description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, tenetur natus doloremque laborum quos iste ipsum rerum obcaecati impedit odit illo dolorum ab tempora nihil dicta earum fugiat. Temporibus, voluptatibus. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, tenetur natus doloremque laborum quos iste ipsum rerum obcaecati impedit odit illo dolorum ab tempora nihil dicta earum fugiat. Temporibus, voluptatibus.",
      "Summary": "They're just as round as donuts, but far more healthy! Freshly made every morning before sunrise.",
      "Name": "Fresh Bagels",
      "ImageFile": "bagel.png"
    },
    {
      "ID": "5",
      "Description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, tenetur natus doloremque laborum quos iste ipsum rerum obcaecati impedit odit illo dolorum ab tempora nihil dicta earum fugiat. Temporibus, voluptatibus. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, tenetur natus doloremque laborum quos iste ipsum rerum obcaecati impedit odit illo dolorum ab tempora nihil dicta earum fugiat. Temporibus, voluptatibus.",
      "Summary": "We've got strawberries, blueberries, apples, bananas - we could list them all, but we'd prefer you come take a look!",
      "Name": "Fresh Fruit",
      "ImageFile": "strawberries.png"
    }
  ]
}

【问题讨论】:

  • 菜单不是列表,使用JsonConvert.DeserializeObject&lt;Menu&gt;(json);

标签: c# json serialization json.net


【解决方案1】:

您正在尝试将 json 反序列化为 List&lt;Menu&gt;

JsonConvert.DeserializeObject<List<Menu>>(json);

但是 json 不包含一个菜单列表,它只包含一个菜单对象。可以看到json以{ }开头

{
    "Test": [...]
}

{ } 是一个对象,[ ] 是一个数组。因此,为了能够反序列化为菜单列表,您的 json 应该如下所示:

[
    {
        "Test": [...]
    }
]

这样你就可以有多个菜单,像这样:

[
    {
        "Test": [...]
    },
    {
        "Test": [...]
    },
    {
        "Test": [...]
    },
]

希望对你有帮助

【讨论】:

  • 我想要实现的是一个带有 Console.WriteLine() 的菜单项列表,例如 Menuitem 1: ID=1 Menuitem 2: ID=2
  • 如果您对拥有多个Menu 不感兴趣,您应该按照@Nouman 的评论将您的代码更改为JsonConvert.DeserializeObject&lt;Menu&gt;(json);。如果您这样做,您将拥有model.Test 成为List&lt;MenuItem&gt;。比你可以循环它并做类似foreach(MenuItem item in model.Test) Console.WriteLine(item.ID);的事情
【解决方案2】:

非常感谢您的回答!

这是工作代码!

using System;
using System.Collections.Generic;
using System.Net;
using Newtonsoft.Json;


namespace ConsoleApp1
{
    public class MenuItem
    {
        public string ID { get; set; }
        public string Description { get; set; }
        public string Summary { get; set; }
        public string Name { get; set; }
        public string ImageFile { get; set; }
    }

    public class Menu
    {
        public List<MenuItem> Test { get; set; }
    }


    class Program
    {

        static void Main(string[] args)
        {
          var webclient = new WebClient();
          var json = webclient.DownloadString(@"C:\Users\devuser\source\repos\ConsoleApp1\ConsoleApp1\data.json");
          var model = JsonConvert.DeserializeObject<Menu>(json);

            foreach (var item in model.Test)
            {
                Console.WriteLine("ID: "+item.ID+" "+"Name: "+item.Name);
            }
        }
    }
}
```

【讨论】:

    【解决方案3】:

    改变这一行

    var model = JsonConvert.DeserializeObject<List<Menu>>(json);
    

    var model = JsonConvert.DeserializeObject<Menu>(json);
    

    这是因为给定的 json 表示一个对象 Menu,其中包含一个名为 Test 的 List&lt;MenuItem&gt;

    示例代码。

    DotNetFiddle Code Link

    附:示例代码使用字符串初始化而不是从文件中加载 json。

    【讨论】:

    • 感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2016-10-15
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多