How to handle custom Properties in AutoMapper

Custom mapping can be defined in global.ascx (at startup) by following codes :

      AutoMapper.Mapper.CreateMap<Domain.User, UsersDetailsViewModel>()
          .ForMember(o => o.Email, b => b.MapFrom(z => z.Email))
          .ForMember(o => o.UserName , b => b.MapFrom(user => (user.UserName != null) ? user.UserName : "User" + user.ID.ToString));

you can do some initialization via BeforeMap () method. But you may need to do some changes in your viewmodel.


I think the syntax has slightly changed in 2019 (ASP.NET Core 2.2), this method is now handled with the MapperConfiguration and the static methods are no more available.

But I agree with @KJSR, this post is still really useful :-)

 private Mapper UserMapper= new Mapper(new MapperConfiguration(cfg => (cfg.CreateMap<Domain.User, UsersDetailsViewModel>())
            .ForMember(x=>x.Email, y=>y.MapFrom(z=>z.Email))
            .ForMember(x => x.UserName , y => y.MapFrom(user => (user.UserName != null) ? user.UserName : "User" + user.ID.ToString))));

On automapper where you create the Map you can specify additional processes for specific members of the destination type.

So where your default map would be

Mapper.Map<Domain.User, UsersDetailsViewModel>();

there is a fluent syntax to define the more complicated mappings:

Mapper.Map<Domain.User, UsersDetailsViewModel>()
      .ForMember(vm=>vm.UserName, m=>m.MapFrom(u=>(u.UserName != null) 
                                               ? u.UserName 
                                               : "User" + u.ID.ToString()));

Here the ForMember takes two Arguments the first defines the property that you are mapping to. The second provides a means of defining the mapping. For an example I have copped out and shown one of the easy mappings.

If you require a more difficult mapping, (such as your CurrentUser mapping) you can create a class that implements the IResolver interface, incorporate your mapping logic in that new clases and then add that into the mapping.

Mapper.Map<Domain.User, UsersDetailsViewModel>()
  .ForMember(vm=>vm.IsUserMatch, m=>m.ResolveUsing<MatchingUserResolver>()));

when Mapper comes to do the mapping it will invoke your custom resolver.

Once you discover the syntax of the .ForMember method everything else kind of slots into place.