372

I'm using Automapper and I have the following scenario: Class OrderModel has a property called 'ProductName' that isn't in the database. So when I try to do the mapping with:

Mapper.CreateMap<OrderModel, Orders>(); 

It generates an exception :

"The following 1 properties on Project.ViewModels.OrderModel are not mapped: 'ProductName'

I've read at AutoMapper's Wiki for Projections the opposite case (the extra attribute is on the destination, not in the source which is actually my case )

How can I avoid automapper to make the mapping of this property?

Andries Koorzen
  • 131
  • 2
  • 11
Msam85
  • 3,964
  • 2
  • 18
  • 18
  • 9
    Automapper doesn't work that way. Its only concerned about properties on the destination object. The src can contain 100 extra properties -- Automapper only maps the dest properties. There must be something else causing the mapping exception. Can you post some code of what is not working? – PatrickSteele Oct 30 '10 at 02:57
  • It does what you ask automatically. Post some code to clarify – BeRecursive Nov 10 '10 at 10:18
  • 4
    @Patrick AutoMapper does some tricks with analyzing method/property names. It is possible that there is a property on the source that is being unintentionally mapped even if there isn't an exact match on the destination. This is why there is a ForSourceMember(...Ignore()) to prevent this when it occurs. – AaronLS Jun 15 '12 at 16:40
  • Have a look at the following posts, these might help you http://stackoverflow.com/questions/4456519/how-to-configure-automapper-for-polymorphism-with-explicit-member-mapping http://stackoverflow.com/questions/4052579/automapper-how-to-ignore-property-in-source-item-that-does-not-exist-in-destinati – Divi Feb 14 '11 at 00:54

9 Answers9

653

From Jimmy Bogard: CreateMap<Foo, Bar>().ForMember(x => x.Blarg, opt => opt.Ignore());

It's in one of the comments at his blog.

UPDATE(from Jamie's comment Jan 4 '19 at 11:11:)

Ignore has been replaced with DoNotValidate in ForSourceMember: https://github.com/AutoMapper/AutoMapper/blob/master/docs/8.0-Upgrade-Guide.md

Michael Freidgeim
  • 26,542
  • 16
  • 152
  • 170
smartcaveman
  • 41,281
  • 29
  • 127
  • 212
  • 28
    Also, `CreateMap().ForSourceMember(x => x.Blarg, opt => opt.Ignore());` might be useful – stackoverfloweth Apr 26 '18 at 18:35
  • 22
    @stackoverfloweth Don't you mean: `CreateMap (MemberList.Source).ForSourceMember(x => x.MySourceProperty, opt => opt.DoNotValidate())` ? – monty Dec 03 '18 at 02:40
  • 24
    Ignore has been replaced with DoNotValidate in ForSourceMember: https://github.com/AutoMapper/AutoMapper/blob/master/docs/8.0-Upgrade-Guide.md – Jamie Jan 04 '19 at 11:11
  • 2
    @Jamie @monty - I started to update this re: your comment, but it looks like the syntax change only affects the projection case (where the source property needs to be ignored). The OP's request is to ignore a destination property, so, `Ignore()` remains the correct syntax. This is because the syntax change for `Ignore` was made on the `ISourceMemberConfigurationExpression` interface but not on the disjoint ``IMemberConfigurationExpression`3`` interface. – smartcaveman Jan 11 '19 at 07:48
  • @stackoverfloweth what are the differences between ForSourceMember() and ForMember()? – Franva May 07 '19 at 03:50
  • 3
    @Franva ForMember() is actually "ForDestinationMember()" – rvnlord Aug 02 '19 at 11:45
  • Pay attention if you use ForMember or ForSourceMember. To make it work, you need to use ForMember, and there is still the option Ignore(). – Marcin Apr 29 '23 at 08:37
280

I'm perhaps a bit of a perfectionist; I don't really like the ForMember(..., x => x.Ignore()) syntax. It's a little thing, but it matters to me. I wrote this extension method to make it a bit nicer:

public static IMappingExpression<TSource, TDestination> Ignore<TSource, TDestination>(
    this IMappingExpression<TSource, TDestination> map,
    Expression<Func<TDestination, object>> selector)
{
    map.ForMember(selector, config => config.Ignore());
    return map;
}

It can be used like so:

Mapper.CreateMap<JsonRecord, DatabaseRecord>()
        .Ignore(record => record.Field)
        .Ignore(record => record.AnotherField)
        .Ignore(record => record.Etc);

You could also rewrite it to work with params, but I don't like the look of a method with loads of lambdas.

MarredCheese
  • 17,541
  • 8
  • 92
  • 91
Steve Rukuts
  • 9,167
  • 3
  • 50
  • 72
  • 8
    I know this goes beyond the initial question but I really like this answer, its clean, very easy to read and instantly understand plus easy to reuse – Lski Dec 03 '14 at 16:15
  • Regarding `params`: You could return an array of selectors from inside a single lambda, then map over each selector with `foreach` or `Select()` Perhaps not less messy-looking, though. – jpaugh May 17 '17 at 23:51
  • thanks @Steve Rukuts, for anyone who is looking for extension method to ignore source members you can use this public static IMappingExpression IgnoreSourceValidation( this IMappingExpression map, Expression> selector) { map.ForSourceMember(selector, config => config.DoNotValidate()); return map; } – Jason Dias Dec 18 '19 at 06:04
  • 2
    How does it work for `ReverseMap`? ReverseMap().ForPath(... – serge Feb 18 '21 at 12:23
  • 2
    I think I'd prefer to name it `IgnoreMember()`, but great extension! – Suncat2000 Apr 30 '21 at 15:24
  • Seems like `Ignore()` does not work (I am getting destination field overwritten with default value if such field is missing in source) if I map collection to collection, not entity to entity. – Alexander Sep 21 '21 at 14:52
97

You can do this:

conf.CreateMap<SourceType, DestinationType>()
   .ForSourceMember(x => x.SourceProperty, y => y.Ignore());

Or, in latest version of Automapper, you simply want to tell Automapper to not validate the field

conf.CreateMap<SourceType, DestinationType>()
   .ForSourceMember(x => x.SourceProperty, y => y.DoNotValidate());
DLeh
  • 23,806
  • 16
  • 84
  • 128
Richard
  • 1,219
  • 11
  • 13
  • Does automapper have a ForSourceMember extension? – Redeemed1 May 21 '12 at 14:46
  • I do this currently, but it would be ideal to NOT have to create all these Ignore... :/ – Tom Stickel Mar 14 '13 at 04:49
  • do you know if there's a way to ignore when actually doing the mapping and not when creating the map? – Sam I am says Reinstate Monica Nov 07 '14 at 17:10
  • FYI: merged from http://stackoverflow.com/questions/4052579/automapper-how-to-ignore-property-in-source-item-that-does-not-exist-in-destinat – Shog9 Nov 13 '14 at 21:48
  • 4
    For the scenario given in the question, this should be the accepted answer. The current accepted answer ignores mapping of properties in the destination object. This question is asking about ignoring mappings in the source object. – Rob S. Jan 31 '17 at 15:07
  • 2
    for anyone who is looking for extension method public static IMappingExpression IgnoreSourceValidation( this IMappingExpression map, Expression> selector) { map.ForSourceMember(selector, config => config.DoNotValidate()); return map; } – Jason Dias Dec 18 '19 at 06:02
  • 2
    `Ignore()` is not present on `ForSourceMember()` extension. as @JasonDias says, it should be `DoNotValidate()`. At least in latest version of automapper. – DLeh Sep 21 '20 at 18:26
34

There is now (AutoMapper 2.0) an IgnoreMap attribute, which I'm going to use rather than the fluent syntax which is a bit heavy IMHO.

Vahid Farahmandian
  • 6,081
  • 7
  • 42
  • 62
Guillaume
  • 1,076
  • 10
  • 21
31

Just for anyone trying to do this automatically, you can use that extension method to ignore non existing properties on the destination type :

public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
    var sourceType = typeof(TSource);
    var destinationType = typeof(TDestination);
    var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType)
        && x.DestinationType.Equals(destinationType));
    foreach (var property in existingMaps.GetUnmappedPropertyNames())
    {
        expression.ForMember(property, opt => opt.Ignore());
    }
    return expression;
}

to be used as follow :

Mapper.CreateMap<SourceType, DestinationType>().IgnoreAllNonExisting();

thanks to Can Gencer for the tip :)

source : http://cangencer.wordpress.com/2011/06/08/auto-ignore-non-existing-properties-with-automapper/

Stéphane
  • 11,755
  • 7
  • 49
  • 63
  • 5
    FYI: merged from http://stackoverflow.com/questions/4052579/automapper-how-to-ignore-property-in-source-item-that-does-not-exist-in-destinat – Shog9 Nov 13 '14 at 21:48
  • 3
    This doesn't work when injecting IMapper. Mapper.GetAllTypeMaps doesn't exist in the latest version of AutoMapper. Additionally, when I setup my maps in an AutoMapper.Profile and then subsequently injected IMapper, I got this exception "Mapper not initialized. Call Initialize with appropriate configuration. If you are trying to use mapper instances through a container or otherwise, make sure you do not have any calls to the static Mapper.Map methods, and if you're using ProjectTo or UseAsDataSource extension methods, make sure you pass in the appropriate IConfigurationProvider instance." – Ristogod Dec 27 '16 at 15:36
  • I just get `'Mapper' does not contain a definition for 'GetAllTypeMaps' [DSSTools]` .. – Bassie Apr 27 '18 at 01:07
  • 2
    @Bassie Use `Mapper.Configuration.GetAllTypeMaps()` [source](https://github.com/AutoMapper/AutoMapper/issues/1252) – Mike Bovenlander Aug 20 '18 at 07:18
30

When mapping a view model back to a domain model, it can be much cleaner to simply validate the source member list rather than the destination member list

Mapper.CreateMap<OrderModel, Orders>(MemberList.Source); 

Now my mapping validation doesn't fail, requiring another Ignore(), every time I add a property to my domain class.

Loren Paulsen
  • 8,960
  • 1
  • 28
  • 38
3

Could use IgnoreAttribute on the property which needs to be ignored

Naresh
  • 2,667
  • 13
  • 44
  • 69
2

It is also possible to ignore globally properties like this :

  1. Using the AddGlobalIgnore(string propertyNameStartingWith) method in the mapper configuration to ignore properties with name starting with a specified string.
  2. Using the ShouldMapProperty to provide a predicate and conditionally selecting which properties to map. ShouldMapField and ShouldMapMethod properties are also available.

Usage :

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        // other configs...

        AddGlobalIgnore("foo")); // this will ignore properties with name starting with "foo"
        ShouldMapProperty = p => p.Name != "bar"; // this will ignore properties with name "bar"
    }
}

Or :

var config = new MapperConfiguration(cfg => {
    // other configs...
    cfg.AddGlobalIgnore("foo"); // way 1
    cfg.ShouldMapProperty = p => p.Name != "bar"; // way 2
});
-5

Hello All Please Use this it's working fine... for auto mapper use multiple .ForMember in C#

        if (promotionCode.Any())
        {
            Mapper.Reset();
            Mapper.CreateMap<PromotionCode, PromotionCodeEntity>().ForMember(d => d.serverTime, o => o.MapFrom(s => s.promotionCodeId == null ? "date" : String.Format("{0:dd/MM/yyyy h:mm:ss tt}", DateTime.UtcNow.AddHours(7.0))))
                .ForMember(d => d.day, p => p.MapFrom(s => s.code != "" ? LeftTime(Convert.ToInt32(s.quantity), Convert.ToString(s.expiryDate), Convert.ToString(DateTime.UtcNow.AddHours(7.0))) : "Day"))
                .ForMember(d => d.subCategoryname, o => o.MapFrom(s => s.subCategoryId == 0 ? "" : Convert.ToString(subCategory.Where(z => z.subCategoryId.Equals(s.subCategoryId)).FirstOrDefault().subCategoryName)))
                .ForMember(d => d.optionalCategoryName, o => o.MapFrom(s => s.optCategoryId == 0 ? "" : Convert.ToString(optionalCategory.Where(z => z.optCategoryId.Equals(s.optCategoryId)).FirstOrDefault().optCategoryName)))
                .ForMember(d => d.logoImg, o => o.MapFrom(s => s.vendorId == 0 ? "" : Convert.ToString(vendorImg.Where(z => z.vendorId.Equals(s.vendorId)).FirstOrDefault().logoImg)))
                .ForMember(d => d.expiryDate, o => o.MapFrom(s => s.expiryDate == null ? "" : String.Format("{0:dd/MM/yyyy h:mm:ss tt}", s.expiryDate))); 
            var userPromotionModel = Mapper.Map<List<PromotionCode>, List<PromotionCodeEntity>>(promotionCode);
            return userPromotionModel;
        }
        return null;