web-dev-qa-db-ja.com

Asp.Net Core Web API 2.2コントローラーが完全なJSONを返さない

Asp.Net Core Web API 2.2プロジェクトにWeb APIコントローラーがあります。

Messageboardモデル:

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モデル:

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

これは私のWeb APIコントローラーアクションの1つで、簡潔にするために省略されています。

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

MessageBoardsにGETリクエストを発行すると、正しいJSONの一部しか返されません。 Postmanのhttps://localhost:44384/api/MessageBoards/へのアクセスから返されるJSONは次のとおりです。

[{"id":1、 "name": "テストボード2"、 "description": "テスト用の2番目のメッセージボード。"、 "messages":[{"id":1、 "text": "最初のメッセージを投稿します! "、" user ":" Jesse "、" postedDate ":" 2019-01-01T00:00:00 "、" messageBoardId ":1

JSONは切り捨てられます(このため、醜いブロックであり、Postmanによって美化されません)。これは、おそらく、最初の欠落したJSONアイテムであるため、MessageBoardモデルのMessageプロパティが原因です。

メッセージボードと子メッセージのリストをアクションが正しく返すようにするにはどうすればよいですか?

7
Jack

選択した答えは私の場合も正しかった、私のJSON応答は私のJSON応答の参照ループによって切り捨てられており、ReferenceLoopHandling.Ignoreを設定すると実際に問題が解決しました。ただし、これはモデルの循環参照を維持するため、私の意見では最善の解決策ではありません。より良い解決策は、モデル内の[JsonIgnore]属性を使用することです。

モデルの問題はここにあります:

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

ご覧のように、MessageBoardナビゲーションプロパティは、この応答が切り捨てられる場所です。具体的には、json応答の各メッセージに、応答の各メッセージエントリのすべてのMessageBoard情報が含まれるようにします。 Newtonsoftはこれが好きではありません。解決策は、この循環参照を引き起こすナビゲーションプロパティを単に[JsonIngore]することです。あなたのコードではこれは次のようになります:

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