[英]Asp.Net Core Web API 2.2 Controller not returning complete JSON
I have a Web API Controller in my Asp.Net Core Web API 2.2 project.我的 Asp.Net Core Web API 2.2 项目中有一个 Web API 控制器。
Messageboard
model: 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
model: 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; }
}
This is one of my Web API Controller actions, shortened for brevity:这是我的 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();
}
}
Whenever I issue a GET request to MessageBoards, only part of the correct JSON is returned.每当我向 MessageBoards 发出 GET 请求时,只会返回部分正确的 JSON。 Here is the returned JSON from accessing https://localhost:44384/api/MessageBoards/
on Postman:这是在 Postman 上访问https://localhost:44384/api/MessageBoards/
返回的 JSON:
[{"id":1,"name":"Test Board 2","description":"A 2nd Message board for testing purposes.","messages":[{"id":1,"text":"Posting my first message!","user":"Jesse","postedDate":"2019-01-01T00:00:00","messageBoardId":1 [{"id":1,"name":"Test Board 2","description":"用于测试目的的第二个留言板。","messages":[{"id":1,"text":"发布我的第一条消息!","user":"Jesse","postedDate":"2019-01-01T00:00:00","messageBoardId":1
The JSON is cut-off (hence why it's an ugly block and not beautified by Postman), presumably due to the MessageBoard
property on the Message
model since it is the first missing JSON item. JSON 被截断(因此它是一个丑陋的块并且没有被 Postman 美化),大概是由于Message
模型上的MessageBoard
属性,因为它是第一个丢失的 JSON 项。
How can I make the action correctly return the list of MessageBoards and child Messages?如何使操作正确返回 MessageBoards 和子消息列表?
I see you are using Eager Loading
in your query.我看到您在查询中使用了Eager Loading
。 So add the following configuration in your Startup
class to ignore cycles that it finds in the object graph and to generate JSON
response properly.因此,在您的Startup
类中添加以下配置以忽略它在对象图中找到的循环并正确生成JSON
响应。
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
...
}
For more details: Related data and serialization in EF Core有关更多详细信息: EF Core 中的相关数据和序列化
The selected answer was correct in my case as well, my JSON response was getting truncated by a reference loop in my JSON response, and setting ReferenceLoopHandling.Ignore did indeed solve my issue.所选答案在我的情况下也是正确的,我的 JSON 响应被 JSON 响应中的引用循环截断,并且设置 ReferenceLoopHandling.Ignore 确实解决了我的问题。 However, this is not the best solution in my opinion, as this maintains the circular references in your model.但是,在我看来,这不是最好的解决方案,因为这会维护模型中的循环引用。 A better solution would use the [JsonIgnore] attribute within the model.更好的解决方案是在模型中使用 [JsonIgnore] 属性。
The issue in your model is here:您模型中的问题在这里:
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!!!
}
As you can see, your MessageBoard navigation property is where this response is truncated.如您所见,您的 MessageBoard 导航属性是此响应被截断的位置。 Specifically, it will cause each Message in the json response to contain all of the MessageBoard information for each Message entry in the response.具体来说,它将导致 json 响应中的每个 Message 包含响应中每个 Message 条目的所有 MessageBoard 信息。 Newtonsoft does not like this. Newtonsoft 不喜欢这样。 The solution is to simply [JsonIngore] the navigation properties that cause this circular reference.解决方案是简单地 [JsonIngore] 导致此循环引用的导航属性。 In your code this would be:在您的代码中,这将是:
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.