Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you tell AutoMapper to globally ignore missing properties when mapping?

Tags:

c#

automapper

I have quite a bit of entities and so far, I've been doing stuff like

Mapper.CreateMap<Employee, EmployeeDetailsDTO>()
    .ForSourceMember(mem => mem.NewsPosts, opt => opt.Ignore());

I want to tell AutoMapper to simply ignore missing properties in the destination object without having to specify each of them. So far, I haven't found a way to do so with my multiple SO and Google searches. Anyone has a solution? I'm ready to do some sort of loop or anything, as long as it can be written once and that it will scale with model / dto changes or added properties.

like image 274
Pluc Avatar asked Nov 13 '12 12:11

Pluc


People also ask

How do I ignore property in AutoMapper?

So, the AutoMapper Ignore() method is used when you want to completely ignore the property in the mapping. The ignored property could be in either the source or the destination object.

When should you not use AutoMapper?

If you have to do complex mapping behavior, it might be better to avoid using AutoMapper for that scenario. Reverse mapping can get very complicated very quickly, and unless it's very simple, you can have business logic showing up in mapping configuration.

Does AutoMapper map private properties?

By default, AutoMapper only recognizes public members. It can map to private setters, but will skip internal/private methods and properties if the entire property is private/internal.

Can AutoMapper map collections?

Polymorphic element types in collectionsAutoMapper supports polymorphic arrays and collections, such that derived source/destination types are used if found.


2 Answers

When are you getting the error? Is it when you call AssertConfigurationIsValid ?

If yes, then simply dont call this method

You dont have to call this method, consider the following mapping which works:

public class Foo1
{
    public string Field1 { get; set; }
}
public class Foo2
{
    public string Field1 { get; set; }
    public string Field2 { get; set; }
}

Mapper.CreateMap<Foo1, Foo2>();
var foo1 = new Foo1() {Field1 = "field1"};
var foo2 = new Foo2();
Mapper.Map(foo1, foo2);//maps correctly, no Exception

You may want to call AssertConfigurationIsValid for other mappings to ensure they are correct so instead what you need to do is organize your mappings into Profiles:

public class MyMappedClassesProfile: Profile
{
    protected override void Configure()
    {
        CreateMap<Foo1, Foo2>();
        //nb, make sure you call this.CreateMap and NOT Mapper.CreateMap
        //I made this mistake when migrating 'static' mappings to a Profile.    
    }
}

Mapper.AddProfile<MyMappedClassesProfile>();

and then if you decide you want to check the validity of the mapping (case by case basis in your situation) then call

Mapper.AssertConfigurationIsValid(typeof(MyMappedClassesProfile).FullName);

important in your case and/or any case where you dont call AssertConfigurationIsValid you should use something like AutoFixture and a Unit Test to ensure your mapping is working. (which is the intent of AssertConfigurationIsValid)

like image 141
wal Avatar answered Oct 04 '22 10:10

wal


Suggested in wal's answer "don't call AssertConfigurationIsValid()" is not safe, as it will hide potential errors in mappings.
It's better to explicitly ignore mapping between classes, for which you are sure that all needed properties already mapped correctly. You can use extensions created in AutoMapper: "Ignore the rest"? answer:

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Src, Dest>();
     cfg.IgnoreUnmapped<Src, Dest>();  // Ignores unmapped properties on specific map
});

The overload without parameters cfg.IgnoreUnmapped(this IProfileExpression profile) ignores unmapped properties on all maps and not recommended, because it also hides any potential problems for all classes.

like image 43
Michael Freidgeim Avatar answered Oct 04 '22 09:10

Michael Freidgeim