.net core : incomplete JSON response

后端 未结 6 1865
萌比男神i
萌比男神i 2020-12-18 21:08

I\'m trying to build simple API for training, in my database I got users (firstname, lastname, email password, list) and sports ( name, userID). A

相关标签:
6条回答
  • 2020-12-18 21:12

    Just to add another yet unique scenario where this can occur. This can also happen if your DAL is returning queryables. In my scenario, I was returning a boxed object from the DAL and had something like this as a linq query

     ...
     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 
    

    The Trades query was never being executed even though it's root object had .ToListAsync() called on it. What was happening was that the controller would return the result but only up to the Trades section and the Json would not be terminated properly. I then realized an exception was being caught in some custom middleware I wrote in which it was complaining about the data reader already being open. Without going to deep into my investigation, I assumed it had to do something with the DI and how it was handling the lifecycle of the context. The fix was to just add ToList on the trades. It's an ugly way to pass data from the DAL but this is just a fun project.

    0 讨论(0)
  • 2020-12-18 21:17

    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. 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.

    The issue in your model is here:

    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; }
    }
    

    As you can see, your User navigation property is where this response is truncated. Specifically, it will cause each Sport in the json response to contain all of the user information for each sport entry in the response. Newtonsoft does not like this. The solution is to simply [JsonIngore] the navigation properties that cause this circular reference. In your code this would be:

    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 讨论(0)
  • 2020-12-18 21:21

    Faced similar issue, response was getting truncated. Issue was a getter method which trying to formatting date.

    0 讨论(0)
  • 2020-12-18 21:22

    I had this problem to in one of my projects. This is caused by a self referencing loop.

    You need to create some sort of DTO (Data Transfer Object) which will be used to generate your JSON.

    In your DTO you remove the inverse relationship so you end up having something like

        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; }
        }
    

    You then map your user User and Sport models to your UserDto and SportDto A good tool for doing this mapping is AutoMapper. You can read the docs to see how to get started.

    After the mapping is done, you Send the DTOs as your JSON and not your models.

    0 讨论(0)
  • 2020-12-18 21:26

    I'm running into the same issue right now. You can also change the JSON serialization/configuration settings to ignore self-reference loops, as shown in the accepted answer for this question

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().AddJsonOptions(options => {
            options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        });
    }
    
    0 讨论(0)
  • 2020-12-18 21:35

    In my case this solve my issue on core 3, by using Newtonsoft: https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/formatting?view=aspnetcore-3.0#add-newtonsoftjson-based-json-format-support

    Prior to ASP.NET Core 3.0, the default used JSON formatters implemented using the Newtonsoft.Json package. In ASP.NET Core 3.0 or later, the default JSON formatters are based on System.Text.Json. Support for Newtonsoft.Json based formatters and features is available by installing the Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet package and configuring it in Startup.ConfigureServices.

        public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers()
            .AddNewtonsoftJson();
    }
    
    0 讨论(0)
提交回复
热议问题