Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .net核心:不完整的JSON响应_C#_Asp.net Core_.net Core_Asp.net Core Mvc - Fatal编程技术网

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

C# .net核心:不完整的JSON响应,c#,asp.net-core,.net-core,asp.net-core-mvc,C#,Asp.net Core,.net Core,Asp.net Core Mvc,我正在尝试为培训构建简单的API,在我的数据库中我得到了用户(名字、姓氏、电子邮件密码、list)和运动(名字、用户名)。 当我想要得到我的用户时,我得到了一个填充了运动的对象。但是JSON响应是不完整的,它在中间被“切割”。 [{"firstName":"Nicolas","lastName":"Bouhours","email":"n.bouh@test.com","password":"nico@hotmail.fr","sports":[{"name":"Trail","userId":

我正在尝试为培训构建简单的API,在我的数据库中我得到了用户(名字、姓氏、电子邮件密码、
list
)和运动(名字、用户名)。 当我想要得到我的用户时,我得到了一个填充了运动的对象。但是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;
}
//GET:api/Users
[HttpGet]
公共IEnumerable GetUsers()
{
var users=_context.users.Include(u=>u.Sports.ToList();
返回用户;
}
我的模特们:

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; }
}
public class Sport:BaseEntity
{
公共字符串名称{get;set;}
public int UserId{get;set;}
公共用户{get;set;}
}
公共类用户:BaseEntity
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串电子邮件{get;set;}
公共字符串密码{get;set;}
公共列表运动{get;set;}
}
公共类SportAppContext:DbContext
{
公共SportAppContext(DbContextOptions):基本(选项)
{ }
公共数据库集用户{get;set;}
公共数据库集运动{get;set;}
}

我真的不明白发生了什么,如果你知道的话,我在我的一个项目中遇到了这个问题。这是由自引用循环引起的

您需要创建某种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; }
    }
公共级SportDto
{
公共字符串名称{get;set;}
}
公共类UserDto
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串电子邮件{get;set;}
公共字符串密码{get;set;}
公共列表运动{get;set;}
}
然后将您的用户
user
Sport
型号映射到您的
UserDto
SportDto
进行此映射的一个好工具是。您可以阅读文档以了解如何开始


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

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


在我的例子中,这可以通过使用Newtonsoft解决我在core 3上的问题:

在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中打包并配置它


选择的答案在我的例子中也是正确的,我的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; }
}
public class Sport:BaseEntity
{
公共字符串名称{get;set;}
public int UserId{get;set;}
公共用户{get;set;}//这是循环引用的原因
}
公共类用户:BaseEntity
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串电子邮件{get;set;}
公共字符串密码{get;set;}
公共列表运动{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; }
}
public class Sport:BaseEntity
{
公共字符串名称{get;set;}
public int UserId{get;set;}
[JsonIgnore]
公共用户用户{get;set;}//已修复
}
公共类用户:BaseEntity
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串电子邮件{get;set;}
公共字符串密码{get;set;}
公共列表运动{get;set;}
}

只是为了添加另一个可能发生这种情况的独特场景。如果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 
。。。
RootLevelProp1=“asd”,
RootLevelProp2=“asd”,
Trades=b.Trades.OrderBy(c=>c.Time)。选择(c=>new
{
c、 方向,
c、 价格,
c、 股数,
c、 时间

})//面临类似问题,响应被截断。问题是一个试图格式化日期的getter方法。

试试这个:在我的例子中,添加mapping和viewmodel解决了这个问题,这是一个非常好的干净的解决方案,可以解决不完整的json问题。(Y) 这并不能真正回答问题。如果您有不同的问题,可以单击以提问。一旦你有足够的时间,你也可以吸引更多的注意力-
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; }
}
 ...
 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