web-dev-qa-db-fra.com

Le contrôleur Asp.Net Core Web API 2.2 ne renvoie pas le JSON complet

J'ai un contrôleur API Web dans mon projet Asp.Net Core Web API 2.2.

Messageboard modèle:

public class MessageBoard
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }

        public ICollection<Message> Messages { get; set; }
    }

Message modèle:

public class Message
    {
        public long Id { get; set; }
        public string Text { get; set; }
        public string User { get; set; }
        public DateTime PostedDate { get; set; }

        public long MessageBoardId { get; set; }
        [ForeignKey("MessageBoardId")]
        public MessageBoard MessageBoard { get; set; }
    }

Il s'agit de l'une de mes actions de contrôleur d'API Web, abrégée par souci de concision:

[Route("api/[controller]")]
[ApiController]
public class MessageBoardsController : ControllerBase
{        
      // GET: api/MessageBoards
      [HttpGet]
      public async Task<ActionResult<IEnumerable<MessageBoard>>> GetMessageBoards()
      {
         return await _context.MessageBoards
            .Include(i => i.Messages)
            .ToListAsync();
      }
}

Chaque fois que j'émets une demande GET à MessageBoards, seule une partie du JSON correct est renvoyée. Voici le JSON retourné pour accéder à https://localhost:44384/api/MessageBoards/ sur Postman:

[{"id": 1, "name": "Test Board 2", "description": "Un 2e babillard électronique à des fins de test.", "messages": [{"id": 1, "text": " Affichage de mon premier message! "," Utilisateur ":" Jesse "," postedDate ":" 2019-01-01T00: 00: 00 "," messageBoardId ": 1

Le JSON est coupé (d'où la raison pour laquelle il s'agit d'un bloc laid et non embelli par Postman), probablement en raison de la propriété MessageBoard sur le modèle Message car il s'agit du premier élément JSON manquant.

Comment faire pour que l'action renvoie correctement la liste des tableaux de messages et des messages enfants?

7
Jack

La réponse sélectionnée était également correcte dans mon cas, ma réponse JSON était tronquée par une boucle de référence dans ma réponse JSON et la définition de ReferenceLoopHandling.Ignore a effectivement résolu mon problème. Cependant, ce n'est pas la meilleure solution à mon avis, car cela maintient les références circulaires dans votre modèle. Une meilleure solution utiliserait l'attribut [JsonIgnore] dans le modèle.

Le problème dans votre modèle est ici:

public class MessageBoard
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }

        public ICollection<Message> Messages { get; set; }
    }

public class Message
    {
        public long Id { get; set; }
        public string Text { get; set; }
        public string User { get; set; }
        public DateTime PostedDate { get; set; }

        public long MessageBoardId { get; set; }
        [ForeignKey("MessageBoardId")]
        public MessageBoard MessageBoard { get; set; } //This is the cause of your circular referece!!!
    }  

Comme vous pouvez le voir, votre propriété de navigation MessageBoard est l'endroit où cette réponse est tronquée. Plus précisément, il entraînera chaque message dans la réponse json pour contenir toutes les informations MessageBoard pour chaque entrée de message dans la réponse. Newtonsoft n'aime pas ça. La solution consiste simplement à [JsonIngore] les propriétés de navigation à l'origine de cette référence circulaire. Dans votre code, ce serait:

public class MessageBoard
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }

        public ICollection<Message> Messages { get; set; }
    }

public class Message
    {
        public long Id { get; set; }
        public string Text { get; set; }
        public string User { get; set; }
        public DateTime PostedDate { get; set; }

        public long MessageBoardId { get; set; }

        [JsonIgnore]
        [ForeignKey("MessageBoardId")]
        public MessageBoard MessageBoard { get; set; } //fixed!!!
    }  
0
Kevin Bell