Automapper 6.0. Missing map type configuration or unsupported mapping

I've already seen this question , this one and this one .

And I have this exception when I go from Automapper 3.3.1.0

to Automapper 6.0.1.0

. This code does not throw an exception in Automapper 3.3.1.0

.

I have class 2:

Class 1: (Domain)

public class Movie:IEntityBase
{
    public Movie()
    {
        Stocks = new List<Stock>();
    }

    public int ID { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string Image { get; set; }
    public int GenreId { get; set; }
    public virtual Genre Genre { get; set; }
    public string Director { get; set; }
    public string Writer { get; set; }
    public string Producer { get; set; }
    public DateTime ReleaseDate { get; set; }
    public byte Rating { get; set; }
    public string TrailerURI { get; set; }
    public virtual ICollection<Stock> Stocks { get; set; }
}

      

Class 2:

public class MovieViewModel : IValidatableObject
{
    public int ID { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string Image { get; set; }
    public string Genre { get; set; }
    public int GenreId { get; set; }
    public string Director { get; set; }
    public string Writer { get; set; }
    public string Producer { get; set; }
    public DateTime ReleaseDate { get; set; }
    public byte Rating { get; set; }
    public string TrailerURI { get; set; }
    public bool IsAvailable { get; set; }
    public int NumberOfStocks { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var validator = new MovieViewModelValidator();
        var result = validator.Validate(this);
        return result.Errors.Select(item => new ValidationResult(item.ErrorMessage, new[] { item.PropertyName }));
    }
}

      

I tried to display in the constructor the reasons for the class Automapper 6.0.1.0

does not have a method Configure()

to override:

public class DomainToViewModelMappingProfile : Profile
{
    public override string ProfileName
    {
        get { return "DomainToViewModelMappings"; }
    }

    public DomainToViewModelMappingProfile()
    {
        Mapper.Initialize(cfg => {
           cfg.CreateMap<Genre, GenreViewModel>()
                    .ForMember(vm => vm.NumberOfMovies, map => map.MapFrom(g => g.Movies.Count()));

           cfg.CreateMap<Movie, MovieViewModel>()
             .ForMember(vm => vm.Genre, map => map.MapFrom(m => m.Genre.Name))
             .ForMember(vm => vm.GenreId, map => map.MapFrom(m => m.Genre.ID))
             .ForMember(vm => vm.IsAvailable, map => map.MapFrom(m => m.Stocks.Any(s => s.IsAvailable)))
             .ForMember(vm => vm.NumberOfStocks, map => map.MapFrom(m => m.Stocks.Count))
             .ForMember(vm => vm.Image, map => map.MapFrom(m => string.IsNullOrEmpty(m.Image) == true ? "unknown.jpg" : m.Image));
        });                
        Mapper.AssertConfigurationIsValid();
     }            
  }

      

And I have the following exception:

Missing map type configuration or unsupported mapping.

Display types: Movie β†’ MovieViewModel HomeCinema.Entities.Movie β†’ HomeCinema.Web.Models.MovieViewModel

I tried to find out which property is causing this exception using the method Ignore()

, however I am still getting the above exception.

 cfg.CreateMap<Genre, GenreViewModel>()
                    .ForMember(vm => vm.NumberOfMovies, map => map.MapFrom(g => g.Movies.Count()));

 cfg.CreateMap<Movie, MovieViewModel>()
    .ForMember(vm => vm.Genre, map => map.Ignore())
    .ForMember(vm => vm.GenreId, map => map.Ignore())
    .ForMember(vm => vm.IsAvailable, map => map.Ignore())
    .ForMember(vm => vm.NumberOfStocks, map => map.Ignore())
    .ForMember(vm => vm.Image, map => map.Ignore());

      

Forgot to say that I am calling the following method in Global.asax.cs

:

AutoMapperConfiguration.Configure();

      

Could you tell me what I am doing wrong? Any help would be greatly appreciated.

The most interesting thing is that this code is valid in Automapper 3.3.1.0

.

Update:

It works! :) Thanks to all of you guys and special thanks to @AndriiLitvinov. Working code:

public class DomainToViewModelMappingProfile : Profile
{
    public override string ProfileName
    {
        get { return "DomainToViewModelMappings"; }
    }

    public DomainToViewModelMappingProfile()
    {

        CreateMap<Genre, GenreViewModel>()
                    .ForMember(vm => vm.NumberOfMovies, map => map.MapFrom(g => g.Movies.Count()));

        CreateMap<Movie, MovieViewModel>()
         .ForMember(vm => vm.Genre, map => map.MapFrom(m => m.Genre.Name))
         .ForMember(vm => vm.GenreId, map => map.MapFrom(m => m.Genre.ID))
         .ForMember(vm => vm.IsAvailable, map => map.MapFrom(m => m.Stocks.Any(s => s.IsAvailable)))
         .ForMember(vm => vm.NumberOfStocks, map => map.MapFrom(m => m.Stocks.Count))
         .ForMember(vm => vm.Image, map => map.MapFrom(m => string.IsNullOrEmpty(m.Image) == true ? "unknown.jpg" : m.Image));
     }
}

      

and call Initialize()

only once:

//Global.asax.cs
protected void Application_Start()
{
   var config = GlobalConfiguration.Configuration;

   AreaRegistration.RegisterAllAreas();
   WebApiConfig.Register(config);
   Bootstrapper.Run();
   RouteConfig.RegisterRoutes(RouteTable.Routes);
   GlobalConfiguration.Configuration.EnsureInitialized();
   BundleConfig.RegisterBundles(BundleTable.Bundles);
}

public class AutoMapperConfiguration
{
    public static void Configure()
    {
        Mapper.Initialize(x =>
        {
            x.AddProfile<DomainToViewModelMappingProfile>();
        });
    }
}

public class Bootstrapper
{
    public static void `Run()
    {
        //Configure Autofac
        AutofacWebapiConfig.Initialize(GlobalConfiguration.Configuration);

        //Configure Automapper
        AutoMapperConfiguration.Configure();
    }
}

      

+3


source to share


2 answers


I tried to implement such a mapping locally and it all worked. I assume you have a lot of profiles that everyone calls Mapper.Initialize

, as far as I remember, it is meant to be called only once at application startup, and all profiles should call the CreateMap Method :



public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<Foo, Bar>();
    }
}

      

+6


source


When you call a method Mapper.AssertConfigurationIsValid();

, you must ensure that each property has a valid source and target for the mapping. If you don't have a valid source and target for each property, you will receive an error message. If you look at the error message it will tell you in detail. I just looked at your code, but for example public virtual ICollection<Stock> Stocks { get; set; }

has no mapping.



+1


source







All Articles