6

I am using MVC 6 rc1 with EF 7 rc 1 Code First Model to retrieve data over web api controller. I have 3 tables similar to below.

class Product
{
    public int Id { get; set; }
    public string SomeProperty { get; set; }
    public virtual ICollection<Categorization> Categorizations { get; set; }
    public DateTime SomeProperty2 { get; set; }
    public string SomeProperty3 { get; set; }
    public string SomeProperty4 { get; set; }

}

// NOTE: Entity key should be (ProductId, CategoryId)
class Categorization
{
    public int ProductId { get; set; }
    public Product Product { get; set; }

    public int CategoryId { get; set; }
    public Category Category { get; set; }
}

class Category
{
    public int Id { get; set; }
    public ICollection<Categorization> Categorizations { get; set; }
}

My Controller:

[ActionName("searchProducts")]
        public IEnumerable<Product> searchProducts(string searchText,int? id)
        {
          var ret= db.Products
                .Include(s => s.Categorizations).Take(2).ToList();
          return ret;
        }

Below is my Startup.cs ConfigureServices section.

          services.AddMvc()
                .AddJsonOptions(options=>
                {
                    options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                    options.SerializerSettings.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
                });
            services.AddCors();

            var connectionString = Configuration.GetSection("Data:DefaultConnection:ConnectionString").Value;

            services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<ContractsContext>(options => options.UseSqlServer(connectionString));


            services.AddSingleton(_ => Configuration);
            services.AddSingleton<IContractRepository, ContractRepository>();

When I call the api, I get the error as "Chunked body did not terminate properly with 0-sized chunk" in Fiddler. In fiddler resultset, I see only the first object of expected result set with properties until Categorizations filled and NO properties and remaining objects after that (Incomplete JSON data). If I do not include Categorizations in the result set, it works perfectly fine. Am I missing something? Note: EF is returning data correctly but it's getting chunked in the api call and client is unable to read the data in complete.

TSR
  • 714
  • 2
  • 7
  • 24
  • http://stackoverflow.com/questions/22608564/neterr-incomplete-chunked-encoding-in-chrome-only – Avi Dec 08 '15 at 12:20
  • Tried all those options. Did not work. In my case, it's not just the issue with Chrome, IE, Fiddler, Postman all face the issue. While Postman errors out, Fiddler at least shows that truncated data. – TSR Dec 08 '15 at 12:25
  • 1
    This is looks like infinite loop. product holds Categorizations and Categorizations holds product – Avi Dec 08 '15 at 12:37
  • 1
    Have you tried `var result =db.Products.Include(s => s.Categorizations).ToList();` and then `return result;` – Thom Kiesewetter Dec 08 '15 at 12:39
  • Tried. Did not help. :( – TSR Dec 08 '15 at 12:42
  • Have you tried that the object can be serialized with `new JSONResult(db.Products.Include(s => s.Categorizations));` EF has still a number of bugs. I sees that I also change my linq query in join because of some issue's with the include – Thom Kiesewetter Dec 08 '15 at 14:01
  • My problem was that when I use ToList the object is serialized but the Categorizations was stil a linq query, and I could not serialize the total result – Thom Kiesewetter Dec 08 '15 at 14:08
  • How much data are we talking about here? 10 products? 100? 1 Million? Since we don't have the whole schema, I'm assuming that you are having a ton of data requested then you try to serialize that to JSON. That is going to be a massive string blob. – Maxime Rouiller Dec 08 '15 at 14:40
  • If you've done what @ThomKiesewetter said, can you put a breakpoint on the "return result" line or is the request still running at that point? If you can return the result, try to do a `JsonConvert.Serialize(...)` and please share with us the String Length. – Maxime Rouiller Dec 08 '15 at 14:41
  • 1
    @Avi EF7 does not support Lazy Loading as of yet. You have to be explicit on what you include. In this case, it's only 2 tables. – Maxime Rouiller Dec 08 '15 at 14:42
  • Thanks Thom and @Maxime Rouiller. The data is not heavy and for test sake, I returned only 1 object db.Products .Include(s => s.Categorizations).Take(1).ToList(); The Product table has about 25 props out of which 17 are relational. Though I am not including any relational props except this multi to multi relation, it still fails. When I do not include this but include Single relational props, it is able to load even 100 results with no issues. – TSR Dec 08 '15 at 15:04

2 Answers2

8

Found the issue. Self referencing loop detected for property 'Product' with type 'Product'. Path '[0].Categorizations[0]'.

So, EF fills out both Categorization collection in Product object and also Product object in Categorization. So, while serializing to json it became a infinite loop, like:

Product>Categorizations(eachCategorization - Product>Categorizations(eachCategorization - Product>Categorizations(eachCategorization - Product>Categorizations(....

Solution: Change Startup.cs ConfigureServices section as below

services.AddMvc()
                .AddJsonOptions(options =>
                {
                    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
                });
TSR
  • 714
  • 2
  • 7
  • 24
  • 1
    Thank you for sharing this. It was really helpful. – marianc Aug 04 '16 at 15:49
  • 1
    @TSR you have saved me almost pulling my last hair, I was struggling something wrong with my data design on EF side, but as you mentioned, it was browser's handling of json circular referencing error. – Nexus23 Nov 29 '16 at 16:27
0

First, ensure that you are not sending 1 TB of data on the wire but beside that, I would ensure that you are testing this without Fiddler.

Fiddler have some settings where in some scenario, chunked message can lead to issue.

Please make sure that the decode option is not selected:

Decode Option

If everything else fails, please make sure to give us more details as to your project Startup.cs Configure/ConfigureServices section.

Maxime Rouiller
  • 13,614
  • 9
  • 57
  • 107
  • Thanks. Decode option is not selected, tried other clients without fiddler too with the same result. Below is my Startup.cs ConfigureServices section.`code services.AddMvc(); services.AddCors(); var connectionString = Configuration.GetSection("Data:DefaultConnection:ConnectionString").Value; services.AddEntityFramework() .AddSqlServer() .AddDbContext(options => options.UseSqlServer(connectionString)); services.AddSingleton(_ => Configuration); services.AddSingleton();` – TSR Dec 08 '15 at 15:08
  • Then there is something interfering with the normal flow of your application. It could be custom code or another process on your machine that is blocking requests (firewall, antivirus, antimalware, etc.). Is that problem only on your machine or does this code works on another machine? – Maxime Rouiller Dec 08 '15 at 15:13
  • Could you add that to your question in not in the comment? We're losing all the formatting. – Maxime Rouiller Dec 09 '15 at 17:51
  • Done. Added to the question. – TSR Dec 09 '15 at 18:04