Circular reference causing stack overflow with Automapper

后端 未结 5 943
不思量自难忘°
不思量自难忘° 2020-11-29 09:29

I\'m using Automapper to map my NHibernate proxy objects (DTO) to my CSLA business objects

I\'m using Fluent NHibernate to create the mappings - this is working fine

相关标签:
5条回答
  • 2020-11-29 09:52

    Since this is the #1 google search result, I think there might be some people, like me, coming here who don't get a stackoverflow exception, but find trouble when sending the object (via ASP.NET) to the client, and thus it being JSON serialized.

    So I had the same structure in place, Invoices has multiple InvoiceLines, when I load an Invoice and use the Linq-to-SQL .Include(x => x.InvoiceLines) I get errors when I try to load the object from the Api because each InvoiceLine contains the same Invoice again.

    To solve this, do the following in ASP.NET Core Startup class:

    services.AddMvc().AddJsonOptions(o =>
    {
        o.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        o.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
        o.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
        // ^^ IMPORTANT PART ^^
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    

    So include o.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects; in your JsonConfiguration when adding MVC to your application.

    JSON.Net is taking the extra step to setup each reference with an additional meta-property called “$id”. When JSON.Net encounters the same instance in another place in the object graph, it simply drops a reference to the original instance, instead of duplicating the data, and thus not causing circular reference issues!

    Source: https://johnnycode.com/2012/04/10/serializing-circular-references-with-json-net-and-entity-framework/

    So now I don't have to further edit my AutoMapper configuration.

    0 讨论(0)
  • 2020-11-29 09:56

    Not sure if I should post it here:

    I had the same error after doing an automapper.map in a method. The answer of CularBytes got me thinking that the issue was not automapper related but json related.

    I did:

    Return ok(_service.getDataById(id));
    

    instead of

    Return ok(await _service.getDataById(id));
    

    (I forgot to await an asyc call... rookie mistake I know)

    0 讨论(0)
  • 2020-11-29 10:00

    I was having the same issue and solved it by downgrading to version 4.2.1. apparently the checks for circular references was expensive so they made it default to not check. Migrating to AutoMapper 5 - Circular references

    Supposedly these are supposed to be the settings methods for v 5+ but it didn't work for my data model because we opt'd for complex dto relationships instead of single use dtos for each action.

    // Self-referential mapping
    cfg.CreateMap<Category, CategoryDto>().MaxDepth(3);
    
    // Circular references between users and groups
    cfg.CreateMap<User, UserDto>().PreserveReferences();
    

    http://docs.automapper.org/en/stable/5.0-Upgrade-Guide.html#circular-references

    Automapper is supposed to be able to statically determine if the circular reference settings in v6.1+, So if it doesn't work for you automatically in version v6.1+ contact the automapper team.

    0 讨论(0)
  • 2020-11-29 10:07

    In your Automapper configuration:

    Mapper.Map<OrderLine, OrderLineDTO>()
        .ForMember(m => m.Order, opt => opt.Ignore());
    
    Mapper.Map<Order, OrderDTO>()
        .AfterMap((src, dest) => { 
             foreach(var i in dest.OrderLines) 
                 i.Order = dest;
             });
    
    0 讨论(0)
  • 2020-11-29 10:11

    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.

    0 讨论(0)
提交回复
热议问题