使用JSON.NET和C#读取文件并反序列化JSON失败

使用JSON.NET和C#读取文件并反序列化JSON失败,c#,serialization,json.net,C#,Serialization,Json.net,我有一个名为“movies.JSON”的JSON文件,其中包含一个对象和一个包含3部电影的数组。movies.JSON中的JSON如下所示: { "theMovies": [ { "name": "Starship Troopers", "year": 1997 }, { "name": "Ace Ventura: When Nature Calls", "year": 1995 }, { "

我有一个名为“movies.JSON”的JSON文件,其中包含一个对象和一个包含3部电影的数组。movies.JSON中的JSON如下所示:

{
  "theMovies": [
    {
      "name": "Starship Troopers",
      "year": 1997
    },
    {
      "name": "Ace Ventura: When Nature Calls",
      "year": 1995
    },
    {
      "name": "Big",
      "year": 1988
    }
  ]
}
using (StreamReader file = File.OpenText(@"c:\Temp\movies.json"))
        {
            JsonSerializer serializer = new JsonSerializer();
            Movie movie2 = (Movie)serializer.Deserialize(file, typeof(Movie));
            Console.WriteLine(movie2.Name);
            Console.WriteLine(movie2.Year);
        }
我还有一门课叫电影

public class Movie
{
    public string Name { get; set; }
    public int Year { get; set; }
}
我试图将文件读入字符串,并将JSON反序列化为一种电影类型,如下所示:

 Movie movie1 = JsonConvert.DeserializeObject<Movie>(File.ReadAllText(@"c:\Temp\movies.json"));
两者都不起作用。电影1和电影2在观看窗口中均未显示真实数据:

movie1.Name = null
movie1.Year = 0
movie2.Name = null
movie2.Year = 0

显然,让一个对象内部有一个数组是行不通的。有什么建议吗

类结构应该与json文件匹配

请尝试以下操作:

class MovieList
{
    public List<Movie> TheMovies {get; set;}
}
public class Movie
{
    public string Name { get; set; }
    public int Year { get; set; }
}

using (StreamReader file = File.OpenText(@"c:\Temp\movies.json"))
{
    JsonSerializer serializer = new JsonSerializer();
    MovieList movies = (MovieList)serializer.Deserialize(file, typeof(MovieList));
    foreach(var movie in movies.TheMovies)
    {
        Console.WriteLine(movie.Name);
        Console.WriteLine(movie.Year);
    }
}
class电影制作人
{
公共列表移动{get;set;}
}
公映
{
公共字符串名称{get;set;}
公共整数年{get;set;}
}
使用(StreamReader file=file.OpenText(@“c:\Temp\movies.json”))
{
JsonSerializer serializer=新的JsonSerializer();
MovieList movies=(MovieList)序列化程序。反序列化(文件,typeof(MovieList));
foreach(电影中的var电影。TheMovies)
{
Console.WriteLine(movie.Name);
Console.WriteLine(电影年);
}
}

您试图将列表X对象反序列化为电影对象,但它们不兼容

var myLibrary = JsonConvert.DeserializeObject<MyLibrary>(File.ReadAllText(@"c:\Temp\movies.json"));
var myLibrary=JsonConvert.DeserializeObject(File.ReadAllText(@“c:\Temp\movies.json”);
型号:

class MyLibrary
{
    public List<Movie> theMovies { get; set; }
}

public class Movie
{
    public string name { get; set; } // Changed to lower case, as the json representation.
    public int year { get; set; }
}
类MyLibrary
{
公共列表移动{get;set;}
}
公映
{
公共字符串名称{get;set;}//更改为小写,作为json表示形式。
公共整数年{get;set;}
}

完整的JSON文档不是
电影
,而是一个具有属性
theMovies
的对象,该属性包含
电影
的数组。因此,您无法将完整的JSON文档反序列化为
电影
,因为它的结构与目标类型不匹配

您可以:

  • 创建一个表示整个文档的类并反序列化该类:

    class MyDocument
    {
        [JsonProperty("theMovies")]
        public Movie[] Movies { get; set; }
    }
    
    然后,您可以访问
    document.Movies

  • 或者获取包含第一部电影的节点,并将其反序列化:

    var doc = JObject.Parse(File.ReadAllText(@"c:\Temp\movies.json"));
    var theMovies = doc["theMovies"] as JArray;
    var firstMovie = theMovies[0].ToObject<Movie>();
    
    var doc=JObject.Parse(File.ReadAllText(@“c:\Temp\movies.json”);
    var theMovies=doc[“theMovies”]作为JArray;
    var firstMovie=theMovies[0].ToObject();
    

在JSON中,
[]
中包含的任何内容都表示集合,
{}
中包含的任何内容都表示对象(请参见我的答案)。因此,您可以看到有一个对象包含一个名为“movies的集合,它由3个对象(在本例中为“movies”)组成,每个对象有2个属性。如果您用C#术语来考虑这些,您可以有一个类(作为根对象,我们称之为
MyJsonDocument
)包含
IEnumerable
(作为
movies
集合)来保存每个
Movie
对象

public class MyJsonDocument
{
    //  JsonProperty indicates how each variable appears in the JSON, _
    //  so the deserializer knows that "theMovies" should be mapped to "Movies". _
    //  Alternatively, your C# vars should have the same name as the JSON vars.
    [JsonProperty("theMovies")]
    public List<Movie> Movies { get; set; }
}

public class Movie
{
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("year")]
    public int Year { get; set; }
}
公共类MyJsonDocument
{
//JsonProperty指示每个变量在JSON中的显示方式_
//所以反序列化程序知道“theMovies”应该映射到“Movies”_
//或者,您的C#vars应该与JSON vars具有相同的名称。
[JsonProperty(“theMovies”)]
公共列表电影{get;set;}
}
公映
{
[JsonProperty(“名称”)]
公共字符串名称{get;set;}
[JsonProperty(“年度”)]
公共整数年{get;set;}
}
现在您已设置好结构:

var myJsonDocument = JsonConvert.DeserializeObject<MyJsonDocument>(File.ReadAllText(@"C:\Users\trashr0x\Desktop\movies.json"));
foreach(Movie movie in myJsonDocument.Movies)
{
    Console.WriteLine(string.Format("{0} ({1})", movie.Name, movie.Year));
    // or with C# 6.0:
    Console.WriteLine($"{movie.Name} ({movie.Year})");
}
var myJsonDocument=JsonConvert.DeserializeObject(File.ReadAllText(@“C:\Users\trashr0x\Desktop\movies.json”);
foreach(myJsonDocument.Movies中的电影)
{
WriteLine(string.Format(“{0}({1})”,movie.Name,movie.Year);
//或者使用C#6.0:
Console.WriteLine($“{movie.Name}({movie.Year})”);
}
输出:

星际飞船士兵(1997)

艾斯·文图拉:《当大自然召唤》(1995)

Big(1988年)


作为一个旁白,您可能还想考虑当JSON属性中的一些是空的(例如,没有为特定电影列出的年份)时会发生什么。您必须将

Year
转换为
int?
(可为空的整数),而不是
int
。如果您100%确信JSON中的所有属性都会被填充,那么您可以忽略这一点。

您为单个电影定义了一个类,但没有为包含这些电影的封闭对象定义一个类。。。该对象不是电影。您的json文件表示一个对象,该对象包含一个包含电影数组的属性(
movie[]
),因此这就是您需要反序列化的内容,以感谢所有帮助过您的人!每一个答案都帮助我理解我错在哪里。我将#trashr0x标记为正确答案,因为它似乎是最完整的。嘿,不客气。你也应该对所有你认为有用的答案进行投票。