.NET Core:不完整的JSON响应

19

我正在尝试构建一个简单的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; }
}

我真的不理解发生了什么事情,如果你有任何想法


试试这个:https://dev59.com/R1kT5IYBdhLWcg3wIsId#39024972 - steamer25
6个回答

27

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

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddJsonOptions(options => {
        options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    });
}

在我的情况下,添加映射和视图模型解决了循环问题。 - FindOutIslamNow
非常好且简洁的解决方案,可以解决不完整的JSON问题。 (Y) - Saima

12

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

您需要创建某种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; }
    }

然后您将您的用户User和运动Sport模型映射到您的UserDtoSportDto模型。

一个很好的工具来进行这种映射是AutoMapper。您可以阅读文档以了解如何入门。

映射完成后,您应该发送您的DTOs而不是您的models作为JSON。


1

我来补充一种独特的情况,导致这种问题的发生。如果你的数据访问层(DAL)返回查询对象(queryables),也会出现这种情况。在我的情况中,我从DAL返回了一个装箱对象(boxed object),并使用了类似于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 
< p >即使在其根对象上调用了.ToListAsync()Trades查询也从未被执行。发生的情况是控制器会返回结果,但只限于Trades部分,Json没有正确终止。然后我意识到,在我编写的一些自定义中间件中捕获了异常,它抱怨数据读取器已经打开。在不深入研究的情况下,我假设它与DI以及它如何处理上下文的生命周期有关。解决方法是只需在交易中添加ToList。这是一种丑陋的传递数据方式,但这只是一个有趣的项目。


0
所选答案在我的情况下也是正确的,我的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响应中的每个运动包含响应中每个运动条目的所有用户信息。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; }
}

0

在我的情况下,通过使用Newtonsoft解决了我在core 3上的问题: https://learn.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之前,默认使用Newtonsoft.Json包实现JSON格式化程序。在ASP.NET Core 3.0或更高版本中,默认的JSON格式化程序基于System.Text.Json。通过安装Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet包并在Startup.ConfigureServices中进行配置,可以支持基于Newtonsoft.Json的格式化程序和功能。

    public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
        .AddNewtonsoftJson();
}

-1

遇到类似的问题,响应被截断。问题出在一个试图格式化日期的 getter 方法上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接