【问题标题】:net core API controller is returning incomplete json网络核心 API 控制器返回不完整的 json
【发布时间】:2019-08-22 20:05:52
【问题描述】:

几天前我问了一个关于我正在使用实体框架制作的网络核心游戏的问题。

我遇到了一个问题,控制器返回了重复的 JSON 数据。

根据其中一个答案,我将该控制器更改为:

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

由于我更改了控制器,我不得不修改这个模型类,所以我添加了一个名为 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; }
    }

由于我添加了新的“房间”属性,我必须创建一个名为 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; }
   }

构建并运行游戏,我现在得到了一组地牢数据,但它没有返回任何房间。

起初,基于这个 Stack Overflow 问题,.net core : incomplete JSON response,我认为这是因为我需要将其添加到我的 Startup.cs 文件中:

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

但事实并非如此。

于是我花了一个晚上尝试了一堆不同的方法来编写控制器,但它们要么产生了相同的结果,要么只是抛出了一个错误。

今天早上查看代码,我意识到了一些事情。在我的控制器中,创建新“GameDungeon”的第一个选择语句是从 _context.DungeonList 获取数据。

DungeonList 是 Entity Framework 从我数据库中的真实表生成的模型。

但 GameDungeonRoom 只是我创建的一个新的类模型。它基于我的数据库中名为 RoomList 的表,但 _context 中没有任何内容专门处理 GameDungeonRoom。

所以我想知道,我应该引入另一个看起来像这样的控制器吗?

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

然后以某种方式将其附加到 GameDungeon 对象。

我在午饭后尝试过,但结果只是创建了一堆乱七八糟的代码,造成了更大的错误,所以我把它全部删除了。

无论如何,这就是我的 JSON 目前所处的位置:

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

您会注意到“房间”是空的。我不太清楚为什么会这样,或者发生了什么。

我有一个想法,也许我应该创建一个 API 控制器来获取特定地牢的地牢数据。然后创建另一个 API 控制器来获取特定地牢的房间数据。

然后让客户端调用两个控制器(使用相同的dungeonId)并在客户端合并数据。

所以我想知道是否有人能想到为什么“房间”对象是空的。

谢谢!

【问题讨论】:

  • 您是否更改了查询以返回房间?如果你不告诉它,实体通常不会知道获取相关数据。
  • @computercarguy 在我的控制器中我做了......但我想知道我是否需要在其他地方这样做
  • 如果您使用相同的模型从查询到 JSON 返回到客户端,您不应该修改任何内容。您可能必须修改客户端模型才能正确接收它,但如果该 JSON 是传输到客户端的内容(通过 Fiddler 找到或查看浏览器控制台中的网络流量),那么您需要验证房间实际上是正确查询。它要么没有获取数据,要么没有正确插入到您的GameDungeonRoom 模型中。我感觉您需要将您的 Key 移动到 DungeonId 并输入 [ForeignKey("GameDungeon"))
  • 如果我的最后一条评论恰好是答案,我可以将其作为答案,以便对其进行投票和/或接受。
  • 嗨@computercarguy,我不确定我是否理解您的评论。所以也许我应该在我的 GameDungeonRoom 类中添加一个外键?谢谢

标签: linq asp.net-core entity-framework-core asp.net-core-webapi


【解决方案1】:

只是猜测您可能由于缓存了数据上下文而在结果集中遇到了循环引用。因此 Json 序列化程序无法正确序列化它并提供不完整的 json 内容。所以你能试着关注一下吗?

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

【讨论】:

  • 嗨 Wijitha,添加 .AsNoTracking() 产生了相同的结果。
  • @SkyeBoniwell,在返回数据之前,您可以调试并检查对象中的内容。然后做 Newtosoft.Json.Serialize(dungeons)。看看你的结果能否成功转换为 Jason。
  • 还要检查您是否在 DB 上下文中设置了急切加载。
  • 如何启用即时加载?谢谢
猜你喜欢
  • 1970-01-01
  • 2018-11-17
  • 2017-07-29
  • 2021-09-24
  • 2017-05-27
  • 1970-01-01
  • 1970-01-01
  • 2017-12-31
  • 2019-05-26
相关资源
最近更新 更多