I have the following models:
public class MasterData
{
[Key]
public Guid ID { get; set; }
[Required]
public string Name { get; set; }
[InverseProperty(nameof(DetailData.MasterData))]
public List<Detaildata> Details { get; set; }
}
public class DetailData
{
[Key]
public Guid ID { get; set; }
[Required]
public string Name { get; set; }
[InverseProperty(nameof(ChildData.DetailData))]
public List<ChildData> Children { get; set; }
public Guid MasterDataID { get; set; }
[ForeignKey(nameof(MasterDataID))]
public MasterData MasterData { get; set; }
}
public class ChildData
{
[Key]
public Guid ID { get; set; }
[Required]
public string Name { get; set; }
public Guid SectionID { get; set; }
[ForeignKey(nameof(SectionID))]
public Section ChildSection { get; set; }
public Guid DetailDataID { get; set; }
[ForeignKey(nameof(DetailDataID))]
public DetailData DetailData { get; set; }
}
To make sure that the migration is well generated and to avoid shadow properties, I add the InverseProperty
attribute to define both ends of the relationship.
However, when I try to serialize the instances, I get the following exception:
Self referencing loop detected for property 'DetailData' with type 'Models.DetailData'. Path 'Value.Item1.Details[0].Children[0]'.
Well, obviously it is a self referencing loop, as MasterData
has a DetailData
that has a MasterData
navigation object back - as it should be in a navigational relationship.
Unfortunately, I need to serialize these objects.
A workaround would be to mark the InverseProperty
properties with the JsonIgnore
attribute, but I'm not sure what it would cause in the deserializing side of the project.
What should I do to avoid the self referencing loop without ignoring the navigation properties?
You could ignore circular reference globally by editing your WebApiConfig.cs
and putting the following code:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
If you're using .NET Core edit the Startup.cs
to add
var mvc = services.AddMvc(options =>
{
...
})
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
It is possible yet to use annotations to solve this by putting [JsonIgnore]
on the Details
property.