0

I have tried this answer: automapper multi objects to one object. However, my second mapping mapper.Map(additionalUploadSongViewModel, songs); is still overwriting the other fields with default values, it is mapping BuyLink and Lyrics correctly though.

namespace App
{
    public static class AutoMapper
    {
        public static MapperConfiguration Config;

        public static void Initialize()
        {
            //Removed other mappings for verbose
            Config = new MapperConfiguration(x => {
                x.CreateMap<UploadSongViewModel, Song>()
                .IgnoreAllNonExisting()
                .ForMember(a => a.AudioName, m => m.MapFrom(s => s.SongName))
                .ForMember(a => a.AudioPath, m => m.MapFrom(s => s.SongPath));

                x.CreateMap<AdditionalUploadSongViewModel, Song>()
                .IgnoreAllNonExisting();
            });

            //No errors here
            Config.AssertConfigurationIsValid();
        }
    }
}

IgnoreAllNonExisting() is just an extension method that should ignore properties that aren't set in both models, I thought this would fix the problem but it hasn't.

public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
    foreach (var property in expression.TypeMap.GetUnmappedPropertyNames())
    {
        expression.ForMember(property, opt => opt.Ignore());
    }
    return expression;
}

Domain Models:

public abstract class Entity
{
    public int Id { get; set; }
}

public abstract class Audio : Entity
{
    public string AudioName { get; set; }
    public string AudioPath { get; set; }
    public string CoverImagePath { get; set; }
}

public class Song : Audio
{
    //Removed some for verbose
    public string AlbumName { get; set; }
    public string ArtistName { get; set; }
    public string Lyrics { get; set; }
    public string BuyLink { get; set; }
}

ViewModels:

public class UploadSongViewModel
{
    public int Id { get; set; }
    public string SongName { get; set; }
    public string ArtistName { get; set; }
    public string AlbumName { get; set; }
    public string SongPath { get; set; }
    public string CoverImagePath { get; set; }
}

public class AdditionalUploadSongViewModel
{
    public string BuyLink { get; set; }
    public string Lyrics { get; set; }
}

Controller:

[HttpPost]
public async Task<ActionResult> UploadMusic(IList<UploadSongViewModel> uploadSongsViewModel, IList<AdditionalUploadSongViewModel> additionalUploadSongViewModel)
{
     //uploadSongViewModel and additionalUploadSongViewModel has all properties filled out properly here.

     IMapper mapper = AutoMapper.Config.CreateMapper();
     List<Song> songs = mapper.Map<List<UploadSongViewModel>, List<Song> (uploadSongsViewModel.ToList());

     //songs now have proper mapped properties from uploadSongsViewModel

     mapper.Map(additionalUploadSongViewModel, songs);

     //all songs properties (songName, artistName etc) have now been overwritten by additionalUploadSongViewModel properties, instead of only BuyLink and Lyrics.
}
Community
  • 1
  • 1
Martin Dawson
  • 7,455
  • 6
  • 49
  • 92
  • 1
    http://stackoverflow.com/questions/32120042/automapper-creating-new-instance-rather-than-map-properties .. this is a strange idea using two separate collections.. how do you even know that item 2 in collection 1 matches item 2 inc collection 2 every time? – JamieD77 Mar 30 '16 at 15:27
  • @JamieD77 Thanks for the link. Seems like it's my problem. I don't understand your follow up question though. – Martin Dawson Mar 30 '16 at 15:34
  • I was just wondering what would happen if `uploadSongsViewModel` has 10 items and `additionalUploadSongViewModel` only has 9.. – JamieD77 Mar 30 '16 at 15:37
  • @JamieD77 Ah. It can't. They each must have the same amount. – Martin Dawson Mar 30 '16 at 15:38
  • 1
    have you thought about just making `AdditionalUploadSongViewModel` a property of `UploadSongViewModel`? Automapper can handle that – JamieD77 Mar 30 '16 at 15:41
  • @JamieD77 Thanks! I hadn't. I'll try that – Martin Dawson Mar 30 '16 at 15:44

0 Answers0