{"action":"created","issue":{"url":"https://api.github.com/repos/aspnet/IISIntegration/issues/285","repository_url":"https://api.github.com/repos/aspnet/IISIntegration","labels_url":"https://api.github.com/repos/aspnet/IISIntegration/issues/285/labels{/name}","comments_url":"https://api.github.com/repos/aspnet/IISIntegration/issues/285/comments","events_url":"https://api.github.com/repos/aspnet/IISIntegration/issues/285/events","html_url":"https://github.com/aspnet/IISIntegration/issues/285","id":183169992,"number":285,"title":"Json Serializer ReferenceLoopHandling Issue?","user":{"login":"divega","id":1253414,"avatar_url":"https://avatars.githubusercontent.com/u/1253414?v=3","gravatar_id":"","url":"https://api.github.com/users/divega","html_url":"https://github.com/divega","followers_url":"https://api.github.com/users/divega/followers","following_url":"https://api.github.com/users/divega/following{/other_user}","gists_url":"https://api.github.com/users/divega/gists{/gist_id}","starred_url":"https://api.github.com/users/divega/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/divega/subscriptions","organizations_url":"https://api.github.com/users/divega/orgs","repos_url":"https://api.github.com/users/divega/repos","events_url":"https://api.github.com/users/divega/events{/privacy}","received_events_url":"https://api.github.com/users/divega/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/aspnet/IISIntegration/labels/closed-external","name":"closed-external","color":"ededed"}],"state":"open","locked":false,"assignee":{"login":"divega","id":1253414,"avatar_url":"https://avatars.githubusercontent.com/u/1253414?v=3","gravatar_id":"","url":"https://api.github.com/users/divega","html_url":"https://github.com/divega","followers_url":"https://api.github.com/users/divega/followers","following_url":"https://api.github.com/users/divega/following{/other_user}","gists_url":"https://api.github.com/users/divega/gists{/gist_id}","starred_url":"https://api.github.com/users/divega/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/divega/subscriptions","organizations_url":"https://api.github.com/users/divega/orgs","repos_url":"https://api.github.com/users/divega/repos","events_url":"https://api.github.com/users/divega/events{/privacy}","received_events_url":"https://api.github.com/users/divega/received_events","type":"User","site_admin":false},"assignees":[{"login":"divega","id":1253414,"avatar_url":"https://avatars.githubusercontent.com/u/1253414?v=3","gravatar_id":"","url":"https://api.github.com/users/divega","html_url":"https://github.com/divega","followers_url":"https://api.github.com/users/divega/followers","following_url":"https://api.github.com/users/divega/following{/other_user}","gists_url":"https://api.github.com/users/divega/gists{/gist_id}","starred_url":"https://api.github.com/users/divega/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/divega/subscriptions","organizations_url":"https://api.github.com/users/divega/orgs","repos_url":"https://api.github.com/users/divega/repos","events_url":"https://api.github.com/users/divega/events{/privacy}","received_events_url":"https://api.github.com/users/divega/received_events","type":"User","site_admin":false}],"milestone":null,"comments":8,"created_at":"2016-10-14T23:16:49Z","updated_at":"2016-10-14T23:16:53Z","closed_at":null,"body":"_From @chrisckc on October 5, 2016 6:35_\n\nHi, \r\nI think i may have found an issue when using ReferenceLoopHandling.Error (which seems to be the default), in an MVC Web Api that i am working on. In my scenario i tried loading an entity and its related set of nested entities using the .Include() syntax. I then outputted the set of nested entities in the controller and did not see the result i expected. (I expected an exception be thrown)\r\n\r\nInspecting the resulting object graph before serialization shows that it contains self referencing loops because the context automatically linked up each nested entity back to its parent entity, which itself contains the same nested entities each linked back to their parent entities and so on.\r\n\r\nWhen the controller then serialized the object graph using the json.net ReferenceLoopHandling.Error option, i expected to see an exception raised as per the json.net documentation.\r\n\r\nWhat i found it that no exception is raised, instead the resulting Json outputted by the controller seems to be truncated at the point where i would expect that the circular reference was detected/encountered during serialization. \r\n\r\nWhat i can see from looking at the Json is an array as the root element as expected,\r\nbut the array only contains the first entity representation (several are present before serialization) and this is only a partial representation, all of the properties that would normally be seen listed after the parent entity navigation property are missing from the representation, however the Json appears to be valid containing the correct closing braces etc.\r\n \r\nHere is the pseudo code in the controller:\r\n \r\n```\r\nOwner owner = _dbContext.Owners.Include(item => item.Dogs).Where(item => item.OwnerId == id).FirstOrDefault();\r\nif (owner == null)\r\n{\r\n\treturn NotFound();\r\n} \r\nelse\r\n{\r\n\tIEnumerable<Dogs> dogs = owner.Dogs.ToList();\r\n\treturn Ok(dogs);\r\n}\r\n```\r\n\r\nUsing the \"ReferenceLoopHandling.Error\" option, the resulting Json is like this:\r\n\r\n```\r\n[\r\n  {\r\n    \"dogId\": \"20000004-1111-1111-1111-111111111111\",\r\n    \"dogName\": \"Fido\",\r\n    \"dogPurchaseDate\": \"2016-09-29T04:31:00+00:00\",\r\n    \"owner\": {\r\n      \"ownerId\": \"10000000-1111-1111-1111-111111111111\",\r\n      \"ownerName\": \"Fred\",\r\n      \"dogs\": []\r\n    }\r\n  }\r\n]\r\n```\r\nInstead of an exception, i have valid Json but with only the first dog entity outputted and there are Dog properties missing that would normally be listed after the \"owner\" property.\r\nThis looks as if the json.net exception is being swallowed somewhere, is this behaviour by design?\r\nI would have thought it be essential that an exception is thrown when a loop is detected to avoid unpredictable output.\r\n\r\nIf i use ReferenceLoopHandling.Ignore, then all of the Dog entities are outputted correctly and owner property of each Dog entity includes the list of nested dog entities except for its own parent Dog entity, which is what i would expect as per the json.net documentation.\r\nThat kind of output is not what i want as it is very bloated, its just to show the difference in the behaviour of the 2 options during some testing.\r\n\r\nI believe this is an EF/MVC issue rather than a json.net issue because if i do this:\r\n\r\n```\r\n//configure the same options used in startup.cs\r\nJsonSerializerSettings settings = new JsonSerializerSettings {\r\n    ContractResolver = new CamelCasePropertyNamesContractResolver(),\r\n    Formatting = Formatting.Indented,\r\n    NullValueHandling = NullValueHandling.Include,\r\n    MissingMemberHandling = MissingMemberHandling.Ignore,\r\n    ReferenceLoopHandling = ReferenceLoopHandling.Error\r\n};\r\nsettings.Converters.Add(new StringEnumConverter());\r\n//now try to serialize the dogs...\r\nstring jsonString = JsonConvert.SerializeObject(dogs, settings);\r\n```\r\nI correctly get an exception:\r\n`Self referencing loop detected with type 'WebAPIApplication.Data.Dog'. Path '[0].Owner.Dogs'.\"`\r\n\r\nThe controller is using json.net for serialization under the hood, so surely this exception should bubble up to the controller rather then be swallowed and result in a partial Json output.\r\n\r\nHere is my json serializer startup.cs config:\r\n\r\n```\r\npublic void ConfigureServices(IServiceCollection services)\r\n{\r\n//other code.........\r\nbuilder.AddJsonOptions(\r\no =>\r\n{\r\n\to.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();\r\n\to.SerializerSettings.Converters.Add(new StringEnumConverter());\r\n\to.SerializerSettings.Formatting = Formatting.Indented;\r\n\to.SerializerSettings.NullValueHandling = NullValueHandling.Include;\r\n\to.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;\r\n\to.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Error;\r\n});\r\n```\r\n\r\nproject.json package versions:\r\n\"Microsoft.AspNetCore.Mvc\": \"1.0.1\",\r\n\"Npgsql.EntityFrameworkCore.PostgreSQL\": \"1.0.2-*\",\r\n\"Npgsql.EntityFrameworkCore.PostgreSQL.Design\": \"1.0.2-*\"\r\n\r\nLooking at other issues logged here it seems like this has occurred previously and has been worked around/avoided so maybe the root cause has not yet been resolved. It also seems that the behaviour may have been different in older versions?\r\n \r\nIssue 4160 mentions the Json truncation, however there seems to be some circular referencing going on in these 2 issues....\r\n[https://github.com/aspnet/Mvc/issues/4160](https://github.com/aspnet/Mvc/issues/4160)\r\nThat issue has been closed and refers to this one instead:\r\n[https://github.com/aspnet/EntityFramework/issues/4646](https://github.com/aspnet/EntityFramework/issues/4646)\r\nwhich then just changes the subject to view models etc. and is closed,  referring back to 4160\r\n\r\nThis also seems similair:\r\n[https://github.com/aspnet/EntityFramework/issues/5429](https://github.com/aspnet/EntityFramework/issues/5429)\n\n_Copied from original issue: aspnet/EntityFramework#6684_"},"comment":{"url":"https://api.github.com/repos/aspnet/IISIntegration/issues/comments/253941848","html_url":"https://github.com/aspnet/IISIntegration/issues/285#issuecomment-253941848","issue_url":"https://api.github.com/repos/aspnet/IISIntegration/issues/285","id":253941848,"user":{"login":"divega","id":1253414,"avatar_url":"https://avatars.githubusercontent.com/u/1253414?v=3","gravatar_id":"","url":"https://api.github.com/users/divega","html_url":"https://github.com/divega","followers_url":"https://api.github.com/users/divega/followers","following_url":"https://api.github.com/users/divega/following{/other_user}","gists_url":"https://api.github.com/users/divega/gists{/gist_id}","starred_url":"https://api.github.com/users/divega/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/divega/subscriptions","organizations_url":"https://api.github.com/users/divega/orgs","repos_url":"https://api.github.com/users/divega/repos","events_url":"https://api.github.com/users/divega/events{/privacy}","received_events_url":"https://api.github.com/users/divega/received_events","type":"User","site_admin":false},"created_at":"2016-10-14T23:16:53Z","updated_at":"2016-10-14T23:16:53Z","body":"_From @halter73 on October 11, 2016 19:30_\n\n@chrisckc I think part of the problem is that the exception that is occurring happens after your controller action returns it's ActionResult.\r\n\r\nFor efficiency reasons, `return Ok(dogs);` doesn't block waiting for `dogs` to be serialized or for the response to be written, so by the time the exception is thrown during serialization it's too late for an exception to be thrown in your action which at this point has already completed. I bet this exception could be handled by some sort of action filter (@rynowak would certainly know), and if not there in some custom middleware.\r\n\r\nI highly recommend setting up the [developer exception page](https://docs.asp.net/en/latest/fundamentals/error-handling.html#using-the-developer-exception-page) (only for development of course) which should show you what exception is being thrown and where. Adding a [console logger](https://docs.asp.net/en/latest/fundamentals/logging.html#configuring-logging-in-your-application) to your application can also help you track down errors like this during development.\r\n\r\nYou mentioned that it seems wrong that a 200 response was received. This happens because the object isn't completely serialized prior to writing response, so by the time the exception is thrown the start of the object (and the 200 status) has already been written. If you look at your browser's developer tools, you should see some indication that the response is incomplete/invalid because the chunked terminator wasn't written. (Unless you're running behind IIS and running into  aspnet/IISIntegration#39)\r\n\r\n"}}
{"actor":{"display_login":"divega"}}