An exception of type 'AutoMapper.AutoMapperMappingException' occurred in AutoMapper.dll but was not handled in user code

21,745

It seems like there is a problem with mapping Authors property. This Aggregate call will throw an exception if the Authors sequence is null or empty.

.ForMember(x => x.Authors, 
           opt => opt.MapFrom(src => src.Book.Authors.Select(x => x.Name).Aggregate((i, j) => i + ", " + j)))
Share:
21,745
Leon Cullens
Author by

Leon Cullens

Available for freelance jobs. Contact me at [email protected].

Updated on July 09, 2022

Comments

  • Leon Cullens
    Leon Cullens almost 2 years

    Somehow my code doesn't work any more (it did work before with the exact same code). This is the problem:

    The code

    I'm trying to map some objects to ViewModels with this code:

    Configuration:

    Mapper.CreateMap<BookcaseItem, FoundBookcaseItemViewModel>()
        .ForMember(x => x.Title, opt => opt.MapFrom(src => src.Book.Title))
        .ForMember(x => x.Authors, opt => opt.MapFrom(src => src.Book.Authors.Select(x => x.Name).Aggregate((i, j) => i + ", " + j)))
        .ForMember(x => x.Identifiers, opt => opt.MapFrom(src => (!string.IsNullOrEmpty(src.Book.Isbn10) ? ("ISBN10: " + src.Book.Isbn10 + "\r\n") : string.Empty) +
                                                                    (!string.IsNullOrEmpty(src.Book.Isbn13) ? ("ISBN13: " + src.Book.Isbn13) : string.Empty)))
        .ForMember(x => x.Pages, opt => opt.MapFrom(src => src.Book.Pages))
        .ForMember(x => x.ImageUri, opt => opt.MapFrom(src => src.Book.ThumbnailUriSmall));
    

    The usage:

    public ActionResult Index()
    {
        string facebookId = _accountService.GetLoggedInUserFacebookId();
    
        IEnumerable<BookcaseItem> items = _bookcaseItemService.GetBookcaseItemsForUser(facebookId);
        IEnumerable<FoundBookcaseItemViewModel> viewModels = items.Select(Mapper.Map<BookcaseItem, FoundBookcaseItemViewModel>);
    
        return PartialView(viewModels);
    }
    

    The error

    This results in the following error:

    An exception of type 'AutoMapper.AutoMapperMappingException' occurred in AutoMapper.dll but was not handled in user code

    The debug data

    First of all I ensure that there are no configuration errors by calling:

    Mapper.AssertConfigurationIsValid();
    

    I've set breakpoints all over my code and try to debug it, but I can't make sense of it. The 'items' collection is filled with data (proxy classes generated by Entity Framework), but the the 'viewModels' collection is filled with strange data. It has a 'message' that says this:

    Mapping types: BookcaseItem_B9B52593B2659AC05C47AB2A6E0F7AEA9989CC34D3527DF5B6AA988ED57166FB -> String System.Data.Entity.DynamicProxies.BookcaseItem_B9B52593B2659AC05C47AB2A6E0F7AEA9989CC34D3527DF5B6AA988ED57166FB -> System.String

    Destination path: FoundBookcaseItemViewModel.Authors

    Source value: System.Data.Entity.DynamicProxies.BookcaseItem_B9B52593B2659AC05C47AB2A6E0F7AEA9989CC34D3527DF5B6AA988ED57166FB

    And then there's a stacktrace property that says:

    at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()

    at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()

    Oh and finally there's another property called 'context' with the following data:

    enter image description here

    Can anyone explain what's going on here and why my code isn't working any longer? I did a couple of changes to my solution recently, but I've rolled them back by Git, so they shouldn't have any effect on the code.

    My setup

    • Visual Studio 12 RC
    • ASP.NET MVC 4
    • .NET Framework 4.0 (I had 4.5 but that caused too many errors, so I rolled back with Git to version 4.0)
    • Entity Framework 5.0 RC
    • AutoMapper 2.1.267

    The entity and ViewModel

    I don't know if it's relevant, but here is the source class for the mapping:

    public class BookcaseItem : Entity
    {
        public Guid Id { get; set; }
        public bool IsRenting { get; set; }
        public bool IsSwapping { get; set; }
        public bool IsSelling { get; set; }
        public decimal RentingPrice { get; set; }
        public decimal SellingPrice { get; set; }
        public string Currency { get; set; }
        public bool IsAvailable { get; set; }
        public virtual Guid BookId { get; set; }
        public virtual Guid UserId { get; set; }
    
        public virtual Book Book { get; set; }
        public virtual User User { get; set; }
    
        public BookcaseItem()
        {
            IsAvailable = true;
            Currency = "USD";
        }
    }
    

    And this is the destination class for the mapping:

    public class FoundBookcaseItemViewModel
    {
        public Guid Id { get; set; }
        public bool IsRenting { get; set; }
        public bool IsSwapping { get; set; }
        public bool IsSelling { get; set; }
        public decimal RentingPrice { get; set; }
        public decimal SellingPrice { get; set; }
        public string Title { get; set; }
        public string Authors { get; set; }
        public string Identifiers { get; set; }
        public int Pages { get; set; }
        public string ImageUri { get; set; }
    }
    
  • Leon Cullens
    Leon Cullens almost 12 years
    Looks like you've found the root of the problem good sir. I've added a null check in the MapFrom() method and now the exception is gone :)
  • Ufuk Hacıoğulları
    Ufuk Hacıoğulları almost 12 years
    @LeonCullens You should add an empty check too.
  • Leon Cullens
    Leon Cullens almost 12 years
    Well, 'Authors' is a collection of strings, so I just check if the collection contains more than 0 items (the strings in the collection can't be null or empty, that's handled elsewhere) :-)
  • Brendan
    Brendan almost 10 years
    Why does Mapper.AssertConfigurationIsValid() pass as true despite of it being invalid at runtime?
  • Ufuk Hacıoğulları
    Ufuk Hacıoğulları almost 10 years
    @Brendan AutoMapper validation checks if the property names and types match on source and destination types. The exception is thrown inside Select method that is called while mapping.