![](/img/trans.png)
[英]ASP.NET Core 2.2 Web API controller inherited from Object class (not from Controller class)
[英]Asp.Net Core Web API 2.2 Controller not returning complete 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 控制器操作之一,为简洁起见缩短:
[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":"Test Board 2","description":"用于测试目的的第二个留言板。","messages":[{"id":1,"text":"发布我的第一条消息!","user":"Jesse","postedDate":"2019-01-01T00:00:00","messageBoardId":1
JSON 被截断(因此它是一个丑陋的块并且没有被 Postman 美化),大概是由于Message
模型上的MessageBoard
属性,因为它是第一个丢失的 JSON 项。
如何使操作正确返回 MessageBoards 和子消息列表?
我看到您在查询中使用了Eager Loading
。 因此,在您的Startup
类中添加以下配置以忽略它在对象图中找到的循环并正确生成JSON
响应。
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
...
}
有关更多详细信息: EF Core 中的相关数据和序列化
所选答案在我的情况下也是正确的,我的 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 响应中的每个 Message 包含响应中每个 Message 条目的所有 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!!!
}
尝试创建并返回一个 DTO 或一个没有循环信息的新结构/类(MessageBoard 有 Message,有 MessageBoard 等...)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.