Last active
January 3, 2016 13:09
-
-
Save lnickers2004/8467962 to your computer and use it in GitHub Desktop.
WebApi 2: JSON Serialization Exception-- self-referencing circular reference exception Solution 1: project anonymous types removing the self-referring offending property
Solution 2: Use a projection into a DTO Model that does not have the self referencing property
Solution 3: Use a projection into a Model Factory to create our DTO with flexibili…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CountingKs.Data; | |
using CountingKs.Data.Entities; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Net.Http; | |
using System.Web.Http; | |
namespace CountingKs.Controllers | |
{ | |
public class FoodsController : ApiController | |
{ | |
private ICountingKsRepository _repo; | |
public FoodsController(ICountingKsRepository repo) | |
{ | |
_repo = repo; | |
} | |
public IEnumerable<object> Get() | |
{ | |
//The following code causes exception | |
// | |
//message: "An error has occurred." | |
//exceptionMessage: "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'." | |
//exceptionType: "System.InvalidOperationException" | |
//stackTrace: null | |
//innerException: { | |
//message: "An error has occurred." | |
//exceptionMessage: "Self referencing loop detected for property 'food' with type 'CountingKs.Data.Entities.Food'. Path '[0].measures[0]'." | |
//exceptionType: "Newtonsoft.Json.JsonSerializationException" | |
// | |
//var results = _repo.GetAllFoodsWithMeasures() | |
// .OrderBy(f => f.Description) | |
// .Take(25) | |
// .ToList(); | |
//There are a few ways to fix this | |
//Method 1: project the childe object without a reference back to the parent of the relation | |
var results = _repo.GetAllFoodsWithMeasures() | |
.OrderBy(f => f.Description) | |
.Take(25) | |
.ToList().Select(f => new{ | |
Description = f.Description, | |
Measures = f.Measures.Select(m => | |
new | |
{ | |
Description = m.Description, | |
Calories = m.Calories | |
}) | |
}); | |
return results; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CountingKs.Data; | |
using CountingKs.Data.Entities; | |
using CountingKs.Models; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Net.Http; | |
using System.Web.Http; | |
namespace CountingKs.Controllers | |
{ | |
public class FoodsController : ApiController | |
{ | |
private ICountingKsRepository _repo; | |
public FoodsController(ICountingKsRepository repo) | |
{ | |
_repo = repo; | |
} | |
public IEnumerable<FoodModel> Get() | |
{ | |
//The following code causes exception | |
// | |
//message: "An error has occurred." | |
//exceptionMessage: "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'." | |
//exceptionType: "System.InvalidOperationException" | |
//stackTrace: null | |
//innerException: { | |
//message: "An error has occurred." | |
//exceptionMessage: "Self referencing loop detected for property 'food' with type 'CountingKs.Data.Entities.Food'. Path '[0].measures[0]'." | |
//exceptionType: "Newtonsoft.Json.JsonSerializationException" | |
// | |
//var results = _repo.GetAllFoodsWithMeasures() | |
// .OrderBy(f => f.Description) | |
// .Take(25) | |
// .ToList(); | |
//There are a few ways to fix this | |
//Method 1: project the childe object without a reference back to the parent of the relation | |
//this is a fragile... | |
//var results = _repo.GetAllFoodsWithMeasures() | |
// .OrderBy(f => f.Description) | |
// .Take(25) | |
// .ToList().Select(f => new{ | |
// Description = f.Description, | |
// Measures = f.Measures.Select(m => | |
// new | |
// { | |
// Description = m.Description, | |
// Calories = m.Calories | |
// }) | |
// }); | |
// return results; | |
//Method 2 add a DTO, ViewModel that holds only what you wish to serialize to clients | |
//(Automapper can help here-- See http://lostechies.com/jimmybogard/2013/08/25/automapper-3-0-released/ | |
var results = _repo.GetAllFoodsWithMeasures() | |
.OrderBy(f => f.Description) | |
.Take(25) | |
.ToList().Select(f => new FoodModel | |
{ | |
Description = f.Description, | |
Measures = f.Measures.Select(m => | |
new MeasureModel | |
{ | |
Description = m.Description, | |
Calories = m.Calories | |
}) | |
}); | |
return results; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CountingKs.Data; | |
using CountingKs.Data.Entities; | |
using CountingKs.Models; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Net.Http; | |
using System.Web.Http; | |
namespace CountingKs.Controllers | |
{ | |
public class FoodsController : ApiController | |
{ | |
private ICountingKsRepository _repo; | |
private ModelFactory _modelFactory; | |
public FoodsController(ICountingKsRepository repo) | |
{ | |
_repo = repo; | |
_modelFactory = new ModelFactory();//we intentionally did not use dependency injection | |
} | |
public IEnumerable<FoodModel> Get() | |
{ | |
//The following code causes exception | |
// | |
//message: "An error has occurred." | |
//exceptionMessage: "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'." | |
//exceptionType: "System.InvalidOperationException" | |
//stackTrace: null | |
//innerException: { | |
//message: "An error has occurred." | |
//exceptionMessage: "Self referencing loop detected for property 'food' with type 'CountingKs.Data.Entities.Food'. Path '[0].measures[0]'." | |
//exceptionType: "Newtonsoft.Json.JsonSerializationException" | |
// | |
//var results = _repo.GetAllFoodsWithMeasures() | |
// .OrderBy(f => f.Description) | |
// .Take(25) | |
// .ToList(); | |
//There are a few ways to fix this | |
//Method 1: project the childe object without a reference back to the parent of the relation | |
//this is a fragile... | |
//var results = _repo.GetAllFoodsWithMeasures() | |
// .OrderBy(f => f.Description) | |
// .Take(25) | |
// .ToList().Select(f => new{ | |
// Description = f.Description, | |
// Measures = f.Measures.Select(m => | |
// new | |
// { | |
// Description = m.Description, | |
// Calories = m.Calories | |
// }) | |
// }); | |
// return results; | |
//Method 2 add a DTO, ViewModel that holds only what you wish to serialize to clients | |
//(Automapper can help here-- See http://lostechies.com/jimmybogard/2013/08/25/automapper-3-0-released/ | |
//var results = _repo.GetAllFoodsWithMeasures() | |
// .OrderBy(f => f.Description) | |
// .Take(25) | |
// .ToList().Select(f => new FoodModel | |
// { | |
// Description = f.Description, | |
// Measures = f.Measures.Select(m => | |
// new MeasureModel | |
// { | |
// Description = m.Description, | |
// Calories = m.Calories | |
// }) | |
// }); | |
// return results; | |
//Method 3: Use a Factory Pattern to return our DTO view models | |
//NOTE: WE CHOOSE NOT to use Automapper, because we want to be able to build return URI's etc into | |
//to return data e.g. HATEOS Hypermedia etc | |
//using a Model Factory, we have only one place to handling Mapping from | |
//Database entities to DTO's | |
var results = _repo.GetAllFoodsWithMeasures() | |
.OrderBy(f => f.Description) | |
.Take(25) | |
.ToList().Select(f => _modelFactory.Create(f)); | |
return results; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
message: "An error has occurred." | |
exceptionMessage: "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'." | |
exceptionType: "System.InvalidOperationException" | |
stackTrace: null | |
innerException: { | |
message: "An error has occurred." | |
exceptionMessage: "Self referencing loop detected for property 'food' with type 'CountingKs.Data.Entities.Food'. Path '[0].measures[0]'." | |
exceptionType: "Newtonsoft.Json.JsonSerializationException" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment