简体   繁体   中英

Create nested JSON with WebAPI C#?

I need to create a nested JSON for a Trivia application using WebAPI. My Database structure is

TriviaQuiz - A Quiz can have many questions. TriviaQuestion - A Question can have many options (choices) TriviaOption - List of answers (choices)

I need to Produce JSON in below Format

{
    "quiz" : [{
        "id" : 1,
        "name" :"Guess Fruit Color",
        "description": "You need to guess color of fruits",
        "questions" : [
            {"id" : 1000 , "quizId" : 1 , "description": "The color of apple is" , "options" : [
                          {"id" : 1 , "questionId" : 1000 , "description" : "Green", "correctAnswer" : false },
                          {"id" : 2 , "questionId" : 1000 , "description" : "Red",   "correctAnswer" : true },
                          {"id" : 3 , "questionId" : 1000 , "description" : "Pink",  "correctAnswer" : false },
                          {"id" : 4 , "questionId" : 1000 , "description" : "Purple", "correctAnswer": false }      
            ]
            },
            {"id" : 1001 , "quizId" : 1 , "description": "The color of mangoss is" , "options" : [
                          {"id" : 5 , "questionId" : 1001 , "description" : "Green", "correctAnswer" : false },
                          {"id" : 6 , "questionId" : 1001 , "description" : "Red",   "correctAnswer" : false },
                          {"id" : 6 , "questionId" : 1001 , "description" : "Yello", "correctAnswer" : true },
                          {"id" : 8 , "questionId" : 1001 , "description" : "Purple", "correctAnswer": false }      
            ]
            }      
        ]}
    ]
}

I have designed my class like

public class TriviaQuiz
    {
        public int id { get; set; }
        public string name { get; set; }
        public string description { get; set; }

        //A Quiz can have many questions
        public virtual List<TriviaQuestion> questions { get; set; }
    }

public class TriviaQuestion
    {
        [Key(), ForeignKey("triviaQuiz")]
        public int id { get; set; }
        public string description { get; set; }

        //Navigation Property to set foreign key relationship
        [JsonIgnore]
        public virtual TriviaQuiz triviaQuiz { get; set; }

       //A question can have many options 
        public virtual List<TriviaOption> options { get; set; }
    }

public class TriviaOption
    {
        public int id { get; set; }
        [ForeignKey("triviaQuestion")]
        //Tell EF That questionId is a Foreign key to TriviaQuestion table
        public int questionId { get; set; }
        public string description { get; set; }
        public Boolean correctAnswer { get; set; }

        //Navigation Property to set up Foreign key relation ship
        [JsonIgnore]
        public virtual TriviaQuestion triviaQuestion { get; set; }
    }

My WebAPI Looks like this

public List<TriviaQuiz> getTopJson()
        {
            return _db.TriviaQuizs.ToList();
        }

Can some some suggest what is the best approach to generate JSON. Should I be creating a ViewModel for this?

When I run this I get an error: One or more validation errors were detected during model generation:

TriviaQuestion_triviaQuiz_Source: : Multiplicity is not valid in Role 'TriviaQuestion_triviaQuiz_Source' in relationship 'TriviaQuestion_triviaQuiz'. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be ' enter code here 1'.

I have already spend a week researching but not able to find anything relevant on the internet, Can some one help.

Can some some suggest what is the best approach to generate JSON. Should I be creating a ViewModel for this?

Nope just configure you web application to return json by default and return the object.

add

    /// <summary>
    /// The Web api config.
    /// </summary>
    public class WebApiConfig
    {
        /// <summary>
        /// Registers the specified configuration.
        /// </summary>
        /// <param name="config">The configuration.</param>
        public static void Register(HttpConfiguration config)
        {
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

            var settings = config.Formatters.JsonFormatter.SerializerSettings;

            settings.Formatting = Formatting.None;
            settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            settings.NullValueHandling = NullValueHandling.Ignore;
            settings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
            settings.DateParseHandling = DateParseHandling.DateTimeOffset;
            settings.Converters.Add(new OptionalJsonConverter());

to your app_start folder

When I run this I get an error: One or more validation errors were detected during model generation:

your using an ORM, I'm guessing from the message. You have a many-to-one defined but neither side owns the relationship. try adding public intTriviaQuiz triviaQuizId { get; set; } public intTriviaQuiz triviaQuizId { get; set; }

As a general observation it looks like your using the same model for both the database and the api. I wouldn't advice this. Rather create models dedicated to the database and ones dedicated to the api (DTO's). Then map between them this may be a 1-1 mapping at present but will save you potential headaches in the long run.

If the only purpose of this application is to provide the data, and not any presentation layer; you don't need to code a view model. It's also generally bad practice to use database layer attributes (Key, ForeignKey etc..) on the objects that you're serializing - you probably want a safer customized serializable version of the objects that you retrieved from database. For now just remove

[Key(), ForeignKey("triviaQuiz")]

and

[ForeignKey("triviaQuestion")]

from the objects, you can include Newtonsoft.JSon library to your project, and then just call

JsonConvert.SerializeObject(_db.TriviaQuizs.ToList());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM