Automapper: Conditionally use mapfrom or ignore based on a condition

Created on 20 Sep 2016  路  16Comments  路  Source: AutoMapper/AutoMapper

I'm not sure if this is possible, but we are having more and more situations where I only want to map a property if some condition exists. I know that if the properties already match you can do something similar as described here (i know the static functions are no longer something we should be doing):

http://stackoverflow.com/questions/2451189/automapper-ignore-on-condition-of

What i'd like to be able to do, is something like this:

config.CreateMap<Models.PaymentCard, Entities.PaymentCard>()
.ForMember(m => m.BillingAddress, m => source.BillingDetails !=null && source.BillingDetails.Address1 !=null ? m.MapFrom(source=> source.BillingDetails != null ? source.BillingDetails.Address1 : "")) : m.Ignore()

but i can't seem to figure out a way to do a custom mapfrom OR ignore based on a condition. basically , i need a way to do a custom mapping or ignore the property based on that condition, not just map or unmap the same name.

Is this something that can be done?

Most helpful comment

    c.CreateMap<Model, Dto>().ForMember(m=>m.Id, o=>
    {
        o.Condition(s=>s.ShortDescription == null);
        o.MapFrom(s=>s.FooId);
    });

All 16 comments

A neat way to possibly solve this is in the .Condition() have two incoming paramters of the configuration expressions. so, the first would be "what should the mapping be if condition is true, and second, what should the mapping be if the condition is false"

i.e.
.Condition(item=>!String.IsNullOrEmpty(item.BillingDetails?.Address1), m=>m.MapFrom(...), m.Ignore())
or
.Condition(item=>!String.IsNullOrEmpty(item.BillingDetails?.Address1), m=>m.MapFrom(...), m.UseDestinationValue())
or
.Condition(item=>!String.IsNullOrEmpty(item.BillingDetails?.Address1), m=>m.MapFrom(...), m.Value("DefaultAddressOrSomething"))

in this way i could even have to separate map froms that might look at other properties or something. That's kind of a basic example since i could just do all of those checks in one .MapFrom, but its more useful in the situation i described, where i want to have the Destination value left alone IFF some condition and still custom map the property

If the mapping condition is met, the destination member is assigned, otherwise no. Apparently you want something else. But I don't see the difference :)

right, but how to do do the .MapFrom() and .Ignore Conditionally? Maybe i'm just confused on how it would work, but lets say I only want to do the custom mapping if the Id is null and the address1 is not null.

according to this example:
https://github.com/AutoMapper/AutoMapper/wiki/Conditional-mapping
the source and destination _properties_ have to match by name. Mine do not. So how do i do what that example describes, AND have a .MapFrom after the .Condition()?

No, they don't have to match. Write what makes sense and see how it works.

I don't know how i'd write it because there's nothing that shows anything that supports that. How do you have a
.ForMember(m => m.BillingAddress1, m=>m.MapFrom(mm=> String.IsNullOrEmpty(mm.Id) && !String.IsNullOrEmpty(mm.BillingDetails?.Address1) ? mm.BillingDetails.Address1 : < how do i do an ignore/usedestinationvalue here, not 'empty string' > )

    c.CreateMap<Model, Dto>().ForMember(m=>m.Id, o=>
    {
        o.Condition(s=>s.ShortDescription == null);
        o.MapFrom(s=>s.FooId);
    });

I think this is better suited for StackOverflow.

Your example doesn't work. I had a value in the destination, and after using that condition, which was NOT met, it nulled the property out.

What version of Automapper are you using? In 4.2.1 I experienced issues with members being mapped even though the Condition was not met. Upgrading to v5.1.1 fixed it, but now when running a custom build of the latest codebase I am seeing the same issue again.

I am on 4.2.1, yes.

What @kopfsick said might be the most accurate. The condition might of been set up to if it fails return something else but set the property regardless. When moving to expressions in 5.x that got fixed, but not sure why it's not working now.

Did anybody find out anything regarding this? I want to try the latest MyGet release, but with this issue I can't.

@kopfsick There is no issue here. Unless you have a failing test.

I just updated the library. This was a problem until then, so i don't agree that it wasn't an issue. but updating did fix what i was doing.

o.PreCondition(s=>s.ShortDescription == null); ?

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings