.net 核心:不完整的 JSON 响应

Posted

技术标签:

【中文标题】.net 核心:不完整的 JSON 响应【英文标题】:.net core : incomplete JSON response 【发布时间】:2017-11-21 18:11:14 【问题描述】:

我正在尝试构建用于训练的简单 API,在我的数据库中我有用户(名字、姓氏、电子邮件密码、list<sports>)和运动(姓名、用户 ID)。 当我想获得我的用户时,一切都很好,我得到了一个充满运动的对象。但是 JSON 响应是不完整的,它在中间被“剪切”了。

["firstName":"Nicolas","lastName":"Bouhours","email":"n.bouh@test.com","password":"nico@hotmail.fr","sports":["name":"Trail","userId":1

这是我的控制器:

// GET: api/Users
[HttpGet]
public IEnumerable<User> GetUsers()

    var users = _context.Users.Include(u => u.Sports).ToList();
    return users;

还有我的模型:

public class Sport : BaseEntity

    public string Name  get; set; 

    public int UserId  get; set; 
    public User User  get; set; 


public class User : BaseEntity

    public String FirstName  get; set; 
    public String LastName  get; set; 
    public String Email  get; set; 
    public String Password  get; set; 

    public List<Sport> Sports  get; set; 


public class SportAppContext : DbContext

    public SportAppContext(DbContextOptions<SportAppContext> options) : base(options)
     

    public DbSet<User> Users  get; set; 
    public DbSet<Sport> Sports  get; set; 

我真的不明白发生了什么,如果你有任何想法

【问题讨论】:

试试这个:***.com/a/39024972/93345 【参考方案1】:

我现在遇到了同样的问题。您还可以更改 JSON 序列化/配置设置以忽略自引用循环,如接受的答案 for this question

所示
public void ConfigureServices(IServiceCollection services)

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

【讨论】:

在我的情况下,添加映射和视图模型可以解决循环 非常好的和干净的解决方案来解决不完整的 json 问题。 (Y)【参考方案2】:

我在我的一个项目中遇到了这个问题。这是由自引用循环引起的。

您需要创建某种 DTO(数据传输对象),用于生成您的 JSON。

在您的 DTO 中,您删除了反向关系,因此您最终会得到类似的东西

    public class SportDto
    
        public string Name  get; set; 
    

    public class UserDto
    
        public String FirstName  get; set; 
        public String LastName  get; set; 
        public String Email  get; set; 
        public String Password  get; set; 

        public List<SportDto> Sports  get; set; 
    

然后您将您的用户 UserSport 模型映射到您的 UserDtoSportDto 进行此映射的一个好工具是AutoMapper。您可以阅读文档以了解如何开始。

映射完成后,您将 DTO 作为 JSON 而不是 模型 发送。

【讨论】:

【参考方案3】:

只是添加另一个可能发生这种情况的独特场景。如果您的 DAL 返回可查询对象,也会发生这种情况。在我的场景中,我从 DAL 返回了一个装箱的对象,并且有类似这样的 linq 查询

 ...
 RootLevelProp1 = "asd",
 RootLevelProp2 = "asd",
 Trades = b.Trades.OrderBy(c => c.Time).Select(c => new
                
                    c.Direction,
                    c.Price,
                    c.ShareCount,
                    c.Time
                ) //<---- This was being returned as a queryable to the controller 

Trades 查询从未被执行,即使它的根对象调用了 .ToListAsync()。发生的事情是控制器将返回结果,但只返回 Trades 部分,并且 Json 不会正确终止。然后我意识到在我编写的一些自定义中间件中捕获了一个异常,它抱怨数据读取器已经打开。在没有深入调查的情况下,我认为它必须对 DI 以及它如何处理上下文的生命周期做一些事情。解决方法是在交易中添加ToList。这是一种从 DAL 传递数据的丑陋方式,但这只是一个有趣的项目。

【讨论】:

【参考方案4】:

就我而言,这通过使用 Newtonsoft 解决了我在核心 3 上的问题: https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/formatting?view=aspnetcore-3.0#add-newtonsoftjson-based-json-format-support

在 ASP.NET Core 3.0 之前,默认使用 JSON 格式化程序 使用 Newtonsoft.Json 包实现。在 ASP.NET Core 3.0 或 稍后,默认的 JSON 格式化程序基于 System.Text.Json。 支持基于 Newtonsoft.Json 的格式化程序和功能 通过安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 打包并在 Startup.ConfigureServices 中进行配置。

    public void ConfigureServices(IServiceCollection services)

    services.AddControllers()
        .AddNewtonsoftJson();

【讨论】:

【参考方案5】:

在我的情况下,所选答案也是正确的,我的 JSON 响应被我的 JSON 响应中的引用循环截断,设置 ReferenceLoopHandling.Ignore 确实解决了我的问题。但是,在我看来,这不是最好的解决方案,因为这会维护模型中的循环引用。更好的解决方案是在模型中使用 [JsonIgnore] 属性。

您的模型中存在问题:

public class Sport : BaseEntity

    public string Name  get; set; 

    public int UserId  get; set; 
    public User User  get; set;   //This is the cause of your circular reference


public class User : BaseEntity

    public String FirstName  get; set; 
    public String LastName  get; set; 
    public String Email  get; set; 
    public String Password  get; set; 

    public List<Sport> Sports  get; set; 

如您所见,您的用户导航属性是此响应被截断的位置。具体来说,它将导致 json 响应中的每个 Sport 包含响应中每个运动条目的所有用户信息。 Newtonsoft 不喜欢这样。解决方案是简单地 [JsonIngore] 导致此循环引用的导航属性。在您的代码中,这将是:

public class Sport : BaseEntity

    public string Name  get; set; 

    public int UserId  get; set; 
    [JsonIgnore]
    public User User  get; set;   //fixed


public class User : BaseEntity

    public String FirstName  get; set; 
    public String LastName  get; set; 
    public String Email  get; set; 
    public String Password  get; set; 

    public List<Sport> Sports  get; set; 

【讨论】:

【参考方案6】:

面临类似问题,响应被截断。问题是尝试格式化日期的 getter 方法。

【讨论】:

以上是关于.net 核心:不完整的 JSON 响应的主要内容,如果未能解决你的问题,请参考以下文章

改造 2.0 如何打印完整的 json 响应?

DS.RESTAdapter 的预期 JSON 响应的完整列表是啥?

服务器返回无效或不完整的 HTTP 响应

如何使用服务器的 JSON 响应对象(而不是完整对象)中的属性来填充 Kendo 网格?

好课推荐:尚硅谷SpringBoot2核心技术与响应式编程高清完整

使用 AFNetworking 未获得完整的响应标头