Donfidididondada
Donfidididondada

Reputation: 23

Deserializing json file into an object C#

I'm practicing c#, and i was trying to read this nested JSON file into a nested object. I think i'm missing something. Here's what i have so far.

Quiz.json:

    {
        "quiz": {
            "sport": {
                "q1": {
                    "question": "Which one is correct team name in NBA?",
                    "options": [
                        "New York Bulls",
                        "Los Angeles Kings",
                        "Golden State Warriros",
                        "Huston Rocket"
                    ],
                    "answer": "Huston Rocket"
                }
            },
            "maths": {
                "q1": {
                    "question": "5 + 7 = ?",
                    "options": [
                        "10",
                        "11",
                        "12",
                        "13"
                    ],
                    "answer": "12"
                },
                "q2": {
                    "question": "12 - 8 = ?",
                    "options": [
                        "1",
                        "2",
                        "3",
                        "4"
                    ],
                    "answer": "4"
                }
            }
        }
    }

Quiz.cs:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Practic
    {
        class Quiz
        {
            public Sport sport { get; set; }
            public Maths maths { get; set; }
        }
    }

Sport.cs:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Practic
    {
        class Sport
        {
            public Q1 q1 { get; set; }
        }
    }

Maths.cs:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Practic
    {
        class Maths
        {
            public Q1  q1 { get; set; }
            public Q2 q2 { get; set; }
        }
    }

Q2.cs:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Practic
    {
        class Q2
        {
            public string question { get; set; }
            public IList<string> options { get; set; }
            public string answer { get; set; }
        }
    }

Q1.cs:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Practic
    {
        class Q1
        {
            public string question { get; set; }
            public IList<string> options { get; set; }
            public string answer { get; set; }
        }
    }

Program.cs:

    using Newtonsoft.Json;
    using System;
    using System.IO;
    
namespace Practic
{
    class Program
    {
        
        static void Main(string[] args)
        {
            Quiz Quiz = JsonConvert.DeserializeObject<Quiz>(File.ReadAllText(@"C:\Users\Anthony Salvatore\source\repos\Practic\Practic\Quiz.json"));

            // deserialize JSON directly from a file
            using (StreamReader file = File.OpenText(@"C:\Users\Anthony Salvatore\source\repos\Practic\Practic\Quiz.json"))
            {
                JsonSerializer serializer = new JsonSerializer();
                Quiz Quiz2 = (Quiz)serializer.Deserialize(file, typeof(Quiz));
                Console.WriteLine(Quiz2.maths);
            }
        }
    }
}

Ideally i want to run the program.cs, and i'm expecting the Quiz object to be populated, and when i print Console.WriteLine(Quiz2.maths); i am expecting an output, but all i get is a blank line. can someone help me with what i'm missing? am i populating the object wrong? or referencing it wrong?

Upvotes: 1

Views: 91

Answers (2)

Mohammed Sajid
Mohammed Sajid

Reputation: 4913

1 - You don't need Q2 class it's same to Q1 class, use just Q1.
2 - You should add a RootObject that contains Quiz property for the json root, and use this class during deserialization instead of Quiz class.

class RootObject
{
    public Quiz Quiz { get; set; }
}

3 - You can't use Console.WriteLine for reference type like Maths, but you can display each property of Maths or Sport.

Result:

RootObject root = JsonConvert.DeserializeObject<RootObject>(File.ReadAllText(@"C:\Users\Anthony Salvatore\source\repos\Practic\Practic\Quiz.json"));
Quiz quiz = root?.Quiz;

// deserialize JSON directly from a file
using (StreamReader file = File.OpenText(@"C:\Users\Anthony Salvatore\source\repos\Practic\Practic\Quiz.json"))
{
    JsonSerializer serializer = new JsonSerializer();
    RootObject root2 = (RootObject)serializer.Deserialize(file, typeof(RootObject));

    Console.WriteLine($"Maths q1: {root2.Quiz.maths.q1.answer}, {root2.Quiz.maths.q1.question}," +
        $" {string.Join(",", root2.Quiz.maths.q1.options)}");

    Console.WriteLine($"Maths q2: {root2.Quiz.maths.q2.answer}, {root2.Quiz.maths.q2.question}," +
        $" {string.Join(",", root2.Quiz.maths.q2.options)}");

    Console.WriteLine($"sport: {root2.Quiz.sport.q1.answer}, {root2.Quiz.sport.q1.question}," +
        $" {string.Join(",", root2.Quiz.sport.q1.options)}");
}

I hope you find this helpful.

Upvotes: 1

Ashish Sojitra
Ashish Sojitra

Reputation: 25

instead of use "q1" and "q2", please use "QuestionNumber" property like "QuestionNumber:1" and assign question number. it will help you to store multiple questions and easy to serialize data.

You can also use dynamic Datatype to read unpredictable JSON format.

Upvotes: 0

Related Questions