Automapper - Missing type map configuration or unsupported mapping

asp.net-mvc automapper c# entity-framework

Question

Been struggling with this for a day now to no avail. I am new to Automapper and I am trying to map a EF domain object with a viewModel but I receive the following exception:

Missing type map configuration or unsupported mapping.\r\n\r\nMapping types:\r\nCatalogueDefinitionFile -> CatalogueDefinitionFileViewModel\r\nDigital.PriceBuilder.Core.Domain.CatalogueDefinitionFile -> Digital.PriceBuilder.Web.Models.CatalogueDefinitionFileViewModel"}

The domain POCO for CatalogueDefinitionFile is:

public class CatalogueDefinitionFile : BaseEntity
{
    public CatalogueDefinitionFile()
    {
        this.ProductDefinitions = new List<ProductDefinition>();            
    }

    public string TargetApplication { get; set; }

    public virtual IList<ProductDefinition> ProductDefinitions { get; set; }

}

Base entity:

public abstract class BaseEntity
{
    public BaseEntity()
    {
        this.CreatedDate = DateTime.Now;
        this.UpdatedDate = DateTime.Now;
        this.IsActive = true;
    }

    public int Id { get; set; }

    public string Name { get; set; }

    public bool IsActive { get; set; }

    public DateTime CreatedDate { get; set; }

    public string CreatedBy { get; set; }

    public DateTime UpdatedDate { get; set; }

    public string UpdatedBy { get; set; }
}

I've created a Profile:

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

    public DomainToViewModelMappingProfile()
    {
        ConfigureMappings();
    }


    /// <summary>
    /// Creates a mapping between source (Domain) and destination (ViewModel)
    /// </summary>
    private void ConfigureMappings()
    {
        var config = new MapperConfiguration(cfg => {
            cfg.CreateMap<ProductDefinition, ProductDefinitionViewModel>().ReverseMap();
            cfg.CreateMap<CatalogueDefinitionFile, CatalogueDefinitionFileViewModel>().ReverseMap();

        });

        IMapper mapper = config.CreateMapper();

        mapper.Map<ProductDefinition, ProductDefinitionViewModel>(new ProductDefinition());
        mapper.Map<CatalogueDefinitionFile, CatalogueDefinitionFileViewModel>(new CatalogueDefinitionFile());


    }
}

The Profile is reference within a AutoMapperConfiguration class which is then referenced in Global.asax:

public class AutoMapperConfiguration
{
    public static void Configure()
    {
        // Create Automapper profiles
        Mapper.Initialize(m =>
        {
            m.AddProfile<DomainToViewModelMappingProfile>();
            m.AddProfile<ViewModelToDomainMappingProfile>();
        });
    }
}

The viewModel looks like this:

public class CatalogueDefinitionFileViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string TargetApplication { get; set; }

    public bool IsActive { get; set; }

    public DateTime CreatedDate { get; set; }

    public string CreatedBy { get; set; }

    public DateTime UpdatedDate { get; set; }

    public string UpdatedBy { get; set; }

    public virtual IList<ProductDefinition> ProductDefinitions { get; set; }
}

Then in my controller I have this:

public ActionResult Index()
    {
        IEnumerable<CatalogueDefinitionFileViewModel> viewModel = null;
        IEnumerable<CatalogueDefinitionFile> files;

        files = _catalogueDefinitionFileService.GetCatalogueDefinitionFiles();

        viewModel = Mapper.Map<IEnumerable<CatalogueDefinitionFile>, IEnumerable<CatalogueDefinitionFileViewModel>>(files);

        return View(viewModel);
    }

The exception is thrown on

viewModel = Mapper.Map<IEnumerable<CatalogueDefinitionFile>, IEnumerable<CatalogueDefinitionFileViewModel>>(files);

Can someone help me understand why this is happening please?

Thanks in advance.

1
1
7/4/2016 10:56:36 AM

Accepted Answer

Your profile doesn't do anything:

public class DomainToViewModelMappingProfile : Profile
{
// etc ...
    private void ConfigureMappings()
    {
        // You are just creating a local mapper config/instance here and then discarding it when it goes out of scope...
        var config = new MapperConfiguration(cfg => {
            cfg.CreateMap<ProductDefinition, ProductDefinitionViewModel>().ReverseMap();
            cfg.CreateMap<CatalogueDefinitionFile, CatalogueDefinitionFileViewModel>().ReverseMap();    
        });

        // I assume this is just test code
        IMapper mapper = config.CreateMapper();    
        mapper.Map<ProductDefinition, ProductDefinitionViewModel>(new ProductDefinition());
        mapper.Map<CatalogueDefinitionFile, CatalogueDefinitionFileViewModel>(new CatalogueDefinitionFile());  
    }
}

Try this:

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

    public DomainToViewModelMappingProfile()
    {
        ConfigureMappings();
    }


    /// <summary>
    /// Creates a mapping between source (Domain) and destination (ViewModel)
    /// </summary>
    private void ConfigureMappings()
    {
        CreateMap<ProductDefinition, ProductDefinitionViewModel>().ReverseMap();
        CreateMap<CatalogueDefinitionFile, CatalogueDefinitionFileViewModel>().ReverseMap();
    }
}

The Profile type your are inheriting probably relates to a map configuration object (hence having similar/same local methods).

Disclaimer: I've not used Automapper for a while, but the above appears to be your issue.

1
7/4/2016 11:30:18 AM

Popular Answer

I just tested and things work fine. The following mapping passes-

        Mapper.CreateMap<CatalogueDefinitionFile, CatalogueDefinitionFileViewModel>();

        var obj = Mapper.Map<IEnumerable<CatalogueDefinitionFileViewModel>>(new List<CatalogueDefinitionFile>{
            new CatalogueDefinitionFile
        {
            Id = 101,
            Name = "test",
            TargetApplication = "test",
            IsActive = false,
            CreatedBy = "test",
            CreatedDate = DateTime.Now,
            UpdatedBy = "test",
            UpdatedDate = DateTime.Now,
            ProductDefinitions = new List<ProductDefinition> { new ProductDefinition { MyProperty = 100 } }}
        });


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow