Using JSON.NET and C# reading file and deserialize the JSON fails

你。 提交于 2019-12-13 16:09:29

问题


I have a JSON file named 'movies.json' which contains an object and an array of 3 movies. The JSON in movies.json looks like this:

{
  "theMovies": [
    {
      "name": "Starship Troopers",
      "year": 1997
    },
    {
      "name": "Ace Ventura: When Nature Calls",
      "year": 1995
    },
    {
      "name": "Big",
      "year": 1988
    }
  ]
}

I also have a class named Movie

public class Movie
{
    public string Name { get; set; }
    public int Year { get; set; }
}

I am trying to read the file into a string and deserialize the JSON to a type of Movie like this:

 Movie movie1 = JsonConvert.DeserializeObject<Movie>(File.ReadAllText(@"c:\Temp\movies.json"));

and like this:

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

Neither one works. Both movie1 and movie2 show no real data the Watch window:

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

Apparently having an object with an array inside is not working. Any suggestions?


回答1:


In JSON, anything enclosed in [ ] denotes a collection and anything enclosed in { } denotes an object (see my answer here). So, you can see that you have an object containing a collection called theMovies, consisting of 3 objects (in this case, movies) with 2 properties each. If you think of these in C# terms, you could have a class (which would act as the root object, let's call it MyJsonDocument) containing an IEnumerable<Movie> (which would act as theMovies collection) to hold each Movie object in.

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

Now that you have your structure set up:

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

Output:

Starship Troopers (1997)

Ace Ventura: When Nature Calls (1995)

Big (1988)

As an aside, you might also want to consider what happens when some of the JSON properties are empty (for example, no year listed for a particular movie). You would have to convert Year to be an int? (nullable integer) instead of an int. If you are 100% confident that all properties in the JSON will be always populated then you can ignore this.




回答2:


The full JSON document is not a Movie, it's an object with a property theMovies that contains an array of Movies. So you can't deserialize the full JSON document into a Movie, since its structure doesn't match the target type.

You can either:

  • create a class that represents the whole document and deserialize this class:

    class MyDocument
    {
        [JsonProperty("theMovies")]
        public Movie[] Movies { get; set; }
    }
    

    You can then access the first item in document.Movies

  • or get the node that contains the first movie, and deserialize it:

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



回答3:


Your class structure should match your json file.

Try the following:

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



回答4:


You're trying to deserialize List X object to Movie object, which they are not compatible.

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

Models:

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


来源:https://stackoverflow.com/questions/35050522/using-json-net-and-c-sharp-reading-file-and-deserialize-the-json-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!