SkyeBoniwell
SkyeBoniwell

Reputation: 7092

net core API controller is returning incomplete json

I asked a question a few days ago regarding a net core game I'm making that is using Entity Framework.

I had one issue where a controller was returning duplicate JSON data.

Based on one of the answers, I changed that controller to this:

    [HttpGet("GetDungeonAndRoomData/{dungeonId}")]
public async Task<ActionResult<GameDungeon>> GetDungeonAndRoomData(Guid dungeonID)
{
    {
    var dungeon = await _context.DungeonList
    .Select(c => new GameDungeon
    {
        DungeonId = c.DungeonId,
        DungeonName = c.DungeonName,
        StartRoom = c.StartRoom,
        Rooms = c.Rooms.Select(n => new GameDungeonRoom
        {
            RoomId = n.RoomId,
            RoomText = n.RoomText,
            TreasureId = n.TreasureId
        })
    }).SingleOrDefaultAsync(c => c.DungeonId == dungeonID);

Since I changed the controller, I had to modify this model class, so I added a new property called Rooms.

    public partial class GameDungeon
    {
       [Key]
       public string DungeonId { get; set; }
       public string DungeonName { get; set; }
       public string StartRoom { get; set; }

       public IEnumerable<GameDungeonRoom> Rooms { get; set; }
    }

Since I added that new "Rooms" property, I had to create a new model called GameDungeonRoom:

public partial class GameDungeonRoom
   {
      public Guid DungeonId { get; set; }
      [Key]
      public string RoomId { get; set; }
      public string RoomText { get; set; }
      public string TreasureId { get; set; }
   }

Building and running the game, I now get one set of dungeon data, but it is not returning any rooms.

At first, and based off this Stack Overflow question, .net core : incomplete JSON response,I thought it was because I needed to add this to my Startup.cs file:

        services.AddMvc()
                .AddJsonOptions(
                    options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
                );

But that was not the case.

So I then spent the evening trying a bunch of different ways of writing the controller, but they either produced the same results or just threw an error.

Reviewing the code this morning, I realized something. In my controller, the first select statement that creates the new "GameDungeon" is getting data from _context.DungeonList.

DungeonList is a model generated by Entity Framework from a real table in my database.

But GameDungeonRoom is just a new class model I created. It's based off a table in my database called RoomList, but there is nothing in _context that specifically handles GameDungeonRoom.

So I am wondering, should I introduce another controller that kind of looks like this?

var rooms = await _context.RoomList
.Select(c => new GameDungeonRoom  ...

And then somehow append that to the GameDungeon object.

I sort of tried that after lunch but ended up just creating a mess of code that created an even bigger mess of errors so I just deleted it all.

Anyway, after all that, this is where my JSON currently stands:

{ 
            "dungeonId" : "293hf938",
            "dungeonName" : "Dungeon of Dread",
            "startRoom" : "bjgh39811ffr",
            "roomId" : "fgf4h635j",
            "roomText" : "A big empty room",
            "treasureId" : "12a",
            "rooms": [

You'll notice that "rooms" is empty. I'm not quite sure why it is, or what's going on.

One idea I had, is maybe I should just create an API controller that get's the dungeon data for a particular dungeon. Then create another API controller that gets the Room data for a particular dungeon.

Then let the client call both controllers(using the same dungeonId) and combine the data on the client side.

So I was wondering if anyone could think of an idea as to why the "rooms" object is empty.

Thanks!

Upvotes: 2

Views: 705

Answers (1)

Wijitha
Wijitha

Reputation: 1389

Just guessing you might have hit a cyclic reference in your result set due to Data Context being cached. Hence Json serializer cannot serialize it properly and give incomplete json content. So can you try following to pin point that.

var dungeon = await _context.DungeonList
    .Select(c => new GameDungeon
    {
        DungeonId = c.DungeonId,
        DungeonName = c.DungeonName,
        StartRoom = c.StartRoom,
        Rooms = c.Rooms.Select(n => new GameDungeonRoom
        {
            RoomId = n.RoomId,
            RoomText = n.RoomText,
            TreasureId = n.TreasureId
        })
    })
.AsNoTracking() //This ignore the cached data
.SingleOrDefaultAsync(c => c.DungeonId == dungeonID);

Upvotes: 1

Related Questions