.net core:不完整的JSON响应

26 浏览
0 Comments

.net core:不完整的JSON响应

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

下面是我的控制器:

// GET: api/Users
[HttpGet]
public IEnumerable 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 Sports { get; set; }
}
public class SportAppContext : DbContext
{
    public SportAppContext(DbContextOptions options) : base(options)
    { }
    public DbSet Users { get; set; }
    public DbSet Sports { get; set; }
}

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

0
0 Comments

在这个问题中,出现了一个特殊的情况。如果您的数据访问层(DAL)返回的是可查询对象(queryables),也会发生这种情况。在我的情况中,我从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 

尽管对根对象调用了.ToListAsync(),但查询Trades从未被执行。问题在于,控制器返回的结果只包括Trades部分,而JSON没有正确地终止。后来我意识到,在我编写的某个自定义中间件中捕获到了一个异常,该异常抱怨数据读取器已经打开。在没有深入调查的情况下,我假设这与依赖注入(DI)以及它如何处理上下文的生命周期有关。解决方法就是在Trades后面添加ToList。这是一种不太优雅的方式来传递DAL中的数据,但这只是一个有趣的项目。

0
0 Comments

问题:.net core中的不完整JSON响应

原因:在序列化JSON时,可能会出现对象之间的循环引用,导致序列化过程中出现问题。

解决方法:可以通过更改JSON序列化/配置设置来忽略自引用循环。具体方法如下:

在ConfigureServices方法中添加以下代码:

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

这样就可以解决不完整JSON响应的问题了。

0
0 Comments

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

你需要创建某种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 Sports { get; set; }
}

然后将你的用户模型 `User` 和运动模型 `Sport` 映射到你的 `UserDto` 和 `SportDto`。

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

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

0