79

We are using Automapper for a project, and seem to get the following error randomly:

AutoMapper.AutoMapperConfigurationException: Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type

The code hasn't been changed in months. I get that error, refresh and the error is gone and page works fine. I'm using

Mapper.AssertConfigurationIsValid();

not sure why it complains the mappings are not good and then a refresh and it's fine again, has anyone run into this? Debugging doesn't help as it's random, sometimes no errors and then other days it will popup somewhere on the site, come back to it and it's fine. The error also comes up on random pages, not the same page, not the same mapping.

Paritosh
  • 4,243
  • 7
  • 47
  • 80
  • 2
    Probably it "works fine" after that because the call to `AssertConfigurationIsValid` happens on app startup, and the app is now started and so it doesn't get called again. – Kirk Woll Dec 08 '14 at 14:22
  • 1
    The inner exception should tell you exactly what the issue is. – Andrew Whitaker Dec 08 '14 at 14:31
  • @KirkWoll I was guessing the same, that it's due to the application starting up for the first time during the day, maybe some thing isn't ready while it's doing it's mapping. I've tried to reset IIS and the app pool but again it's random was not able to replicate the error. – Paritosh Dec 08 '14 at 14:58
  • @AndrewWhitaker the full error is AutoMapper.AutoMapperConfigurationException: Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type RETel -> SelectItem (Destination member list) DomainClasses.RETel -> Models.SelectItem (Destination member list) but again refresh and it's fine, and doesn't always happen on this page for this mapping. I've gotten it on other pages for other mappings, doesn't always happen. – Paritosh Dec 08 '14 at 15:00
  • 4
    Well if you fix the problems as you see them then they won't come up at all anymore. You could also create a unit test that calls `AssertConfigurationIsValid` on your mappings and get a full list of the issues – Andrew Whitaker Dec 08 '14 at 15:01
  • I had my Unit Test calling AssertConfigurationIsValid begin failing after I added a new Model<->DTO mapping. My issue was not setting a matching scope for the members in my data types. Namely my DTO had a: public int memberVar {get;set;} but in my model it was: int memberVar {get;set;} adding the public scope to the model fixed it. – Hinchy Mar 06 '23 at 14:16

3 Answers3

94

Quick intro edit: as @mrTurkay answers below, this can be solved with the following configuration:

cfg.ValidateInlineMaps = false;

However, you should understand why the problem occours in the first place - so feel free to read on.

This problem occours when you're trying to map an object that you didn't create a mapping configuration for. What you need to keep in mind is, that it doesn't have to be the specific object you're trying to map; but one of it's navigation properties.

Say for instance you have a Car.cs that you want to map to a CarDTO.cs

The Car.cs looks like this:

public class Car
{
  public string Color { get; set; }

  public Engine Engine { get; set; }
}

And your DTO looks the same, but has a reference to the EngineDTO instead:

public class CarDTO
{
  public string Color { get; set; }

  public EngineDTO Engine { get; set; }
}

You configured the mapping like this:

    Mapper.CreateMap<DTO.CarDTO, Data.Model.Car>();
    Mapper.CreateMap<Data.Model.Car, DTO.CarDTO>();

    Mapper.CreateMap<DTO.EngineDTO, Data.Model.Engine>();
    Mapper.CreateMap<Data.Model.Engine, DTO.EngineDTO>();

All looks fine, right? However, in your EngineDTO, you probably have a navigation property like, lets say:

public class EngineDTO
{
public List<PartDTO> Parts { get; set; }
}

So while Automapper is Mapping from Engine to EngineDTO, it also tries to Map the PartDTO, but since you forgot to declare the mapping in the global.asax, you get the error:

AutoMapper.AutoMapperConfigurationException: Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type

If you don't want to map certain properties on a class, you can use Ignore:

Mapper.CreateMap<Engine, EngineDTO>()
    .ForMember(x => x.Parts, opt => opt.Ignore());

EDIT:

For a more robust AutoMapper configuration, I suggest that you use mapping profiles, instead of declaring the mapping directly in Global.asax. Here is an Example:

Profile:

public class CarProfile : Profile
{
    public CarProfile ()
    {
        CreateMap<Car, CarDTO>();
    }
}

Global.asax:

Mapper.Initialize(cfg =>
{
     cfg.AddProfile<CarProfile>();
}
MichaelCleverly
  • 2,473
  • 1
  • 24
  • 33
19

it is about validation.

cfg.ValidateInlineMaps = false;

should be enough

mrTurkay
  • 642
  • 1
  • 7
  • 13
  • 7
    This answer is extremely underrated. I have been struggling to convert an old AutoMapper 2.x configuration to 8.x without manually changing hundreds of mapping statements. Almost all of my maps were straightforward Mapper.CreateMap() in the old format. It appears that removing all of those and using AutoMapper.Mapper.Initialize(cfg => { cfg.ValidateInlineMaps = false; cfg.CreateMissingTypeMaps = true; }); in the application startup is a sufficient replacement so far aside from a few edge cases. – Brandon Barkley Mar 13 '19 at 19:38
  • 6
    Neither of these suggestions appear to be valid any more, as MapperConfiguration does not expose a member called ValidateInlineMaps, and Mapper does not expose a member called Initialize. – Jonathon Cowley-Thom Feb 17 '20 at 17:00
1

In my case, I had forgotten to add Map Configuration to MapConfig.cs.

Onat Korucu
  • 992
  • 11
  • 13