Circular Reference Causing Stack Overflow with Automapper

Circular reference causing stack overflow with Automapper

I was having the same issue using EF 6 and AutoMapper 6. Apparently what Kenny Lucero posted led me to the solution. Here's an extract from AM site:

// Circular references between users and groups
cfg.CreateMap<User, UserDto>().PreserveReferences();

Adding PreserveReferences() to both models made it work.

Automapper Circular Reference Infinite loops

In your automapper config you can exclude the offending circular reference pointback.

.ForMember(dest => dest.OffendingVariable, source=> source.Ignore());

The resulting object you get after the automapper finishes will be "smaller" than the "entity" one and can be serialised to JSON without issue.

EDIT: If your true error lies in that you ultimately want to be able to serialise your "infinite" object into JSON, an you don't care about fixing it by fiddling with automapper i can propose "cropping" down the circular point backs of your object with something like this:

List<MasterJobsDTO> mjd = Mapper.Map<List<function>, List<MasterJobsDTO>>(data);

var jsonPrepMJD = new List<MasterJobsDTO>(from m in mjd
select new MasterJobsDTO()
{
id = m.id,
...,
pointBackMember = new PointBackMember(){set all but the virtual pointback}
}.Cast<MasterJobsDTO>();

If the pointBackMember is a list then select from it and cast it too as deep as you need to go

jsonPrepMJD would then be serialisable.

Migrating to AutoMapper 5 - Circular references

PreserveReferences will make the map behave like AutoMapper4 as you are used to. It will make AutoMapper keep track of what is mapped and prevent it from causing an overflow.

The other option is to set a depth that you wish AutoMapper to traverse. With a set depth it will map a self referencing model the number of times specified.

Circular references would be a class such as:

public class Category
{
public int Id {get;set;}
public Category Child {get;set;}
public string Value {get;set;}
}

A class referencing itself, property Child means you can nest this object many times.

ef4 cause Circular reference in web service

There are multiple solutions for your problem and they really depend on the type of service you are using and on the type of serialization:

  • The clean approach is using DTO (data transfer objects) as @Mikael already suggested. DTO is special object which transfers exactly what you need and nothing more. You can simply create DTOs to not contain circular references and use AutoMapper to map between entities and DTOs and vice versa. +1 for @Mikael because he was the first to mentioned this.

All other approaches are based on tweeking serialization as @Haz suggested:

  • WCF and DataContractSerializer: explicitly mark your entities with DataContract[IsReference=true] and all properties with [DataMember] attributes. This will allow you to use circular references. If you are using T4 template to generate entities you must modify it to add these attributes for you.
  • WCF and DataContractSerializer: implicit serialization. Mark one of related navigation properties with [IgnoreDataMember] attribute so that property is not serialized.
  • XmlSerializer: mark one fo related navigation properties with [XmlIgnore] attribute
  • Other serializations: mark one of related navigation properties with [NonSerialized] (+1 for Haz he was the first to mention this) for common serialization or [ScriptIgnore] for some JSON related serialization.


Related Topics



Leave a reply



Submit