DEV Community

Cesar Aguirre
Cesar Aguirre

Posted on โ€ข Originally published at canro91.github.io

1 1 1

TIL: AutoMapper Only Considers Simple Mappings When Validating Configurations

I originally posted this post on my blog.


Oh boy! AutoMapper once again.

Today I have CreateMovieRequest with a boolean property ICanWatchItWithKids that I want to map to a MPA rating. You know G, PG, PG-13...those ones.

If I can watch it with kids, the property MPARating on the destination type should get "General." Anything else gets "Restricted."

To my surprise, this test fails:

using AutoMapper;

namespace TestProject1;

[TestClass]
public class WhyAutoMapperWhy
{
    public class CreateMovieRequest
    {
        public string Name { get; set; }
        public bool ICanWatchItWithKids { get; set; }
    }

    public class Movie
    {
        public string Name { get; set;}
        public MPARating Rating { get; set;}
    }

    public enum MPARating
    {
        // Sure, there are more.
        // But these two are enough.
        General,
        Restricted
    }

    [TestMethod]
    public void AutoMapperConfig_IsValid()
    {
        var mapperConfig = new MapperConfiguration(options =>
        {
            options.CreateMap<CreateMovieRequest, Movie>(MemberList.Source)
                    .ForMember(
                        dest => dest.Rating,
                        opt => opt.MapFrom(src => src.ICanWatchItWithKids
                                                        ? MPARating.General
                                                        : MPARating.Restricted));
        });

        mapperConfig.AssertConfigurationIsValid();
        //           ๐Ÿ‘†๐Ÿ‘†๐Ÿ‘†                                                       
        // AutoMapper.AutoMapperConfigurationException:
        // CreateMovieRequest -> Movie (Source member list)
        // TestProject1.WhyAutoMapperWhy+CreateMovieRequest -> TestProject1.WhyAutoMapperWhy+Movie (Source member list)
        //
        // Unmapped properties:
        // ICanWatchItWithKids
    }
}
Enter fullscreen mode Exit fullscreen mode

It turns out that starting from AutoMapper version 10.0, only source members expressions are considered when validating mappings. And it's buried in the Upgrade Guide here. Arrggg!

Two solutions: One for the lazy and the right one

Since I'm validating mappings based on the source type, I can simply ignore it:

options.CreateMap<CreateMovieRequest, Movie>(MemberList.Source)
    .ForMember(
        dest => dest.Rating,
        opt => opt.MapFrom(src => src.ICanWatchItWithKids ? MPARating.General : MPARating.Restricted))
    .ForSourceMember(src => src.ICanWatchItWithKids, opt => opt.DoNotValidate());
    // ๐Ÿ‘†๐Ÿ‘†๐Ÿ‘†
    // Thanks AutoMapper, I'll take it from here.
Enter fullscreen mode Exit fullscreen mode

It feels like cheating, but it works.

Or, I can use a converter:

options.CreateMap<CreateMovieRequest, Movie>(MemberList.Source)
    .ForMember(
        dest => dest.Rating,
        opt => opt.ConvertUsing( // ๐Ÿ‘ˆ
                new FromBoolToMPARating(), // ๐Ÿ‘ˆ
                src => src.ICanWatchItWithKids));

// And here's the converter: ๐Ÿ‘‡
public class FromBoolToMPARating : IValueConverter<bool, MPARating>
{
    public MPARating Convert(bool sourceMember, ResolutionContext context)
    {
        // Here's the actual mapping: ๐Ÿ‘‡      
        return sourceMember ? MPARating.General : MPARating.Restricted;
    }
}
Enter fullscreen mode Exit fullscreen mode

Another day working with AutoMapper. It would have been way easier mapping that by hand.


Join my email list and get a short, 2-minute email with 4 curated links about programming and software engineering delivered to your inbox every Friday.

Hot sauce if you're wrong - web dev trivia for staff engineers

Hot sauce if you're wrong ยท web dev trivia for staff engineers (Chris vs Jeremy, Leet Heat S1.E4)

  • Shipping Fast: Test your knowledge of deployment strategies and techniques
  • Authentication: Prove you know your OAuth from your JWT
  • CSS: Demonstrate your styling expertise under pressure
  • Acronyms: Decode the alphabet soup of web development
  • Accessibility: Show your commitment to building for everyone

Contestants must answer rapid-fire questions across the full stack of modern web development. Get it right, earn points. Get it wrong? The spice level goes up!

Watch Video ๐ŸŒถ๏ธ๐Ÿ”ฅ

Top comments (0)

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

๐Ÿ‘‹ Kindness is contagious

Please leave a โค๏ธ or a friendly comment on this post if you found it helpful!

Okay