Automapper exception: "Missing type map configuration or unsupported mapping."
Asked Answered
K

5

10

I am trying to use Ninject in an ASP.NET MVC 5 application that uses AutoMapper for mapping the Model to the View Model and vice versa. Unfortunately I get an error message that states that the type map configuration is missing.

I created a Ninject dependency resolver:

namespace MyNamespace.Infrastructure
{
    public class NinjectDependencyResolver: IDependencyResolver
    {
        private IKernel kernel;

        public NinjectDependencyResolver(IKernel kernelParam)
        {
            kernel = kernelParam;
            AddBindings();
        }

        public object GetService(Type serviceType)
        {
            return kernel.TryGet(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return kernel.GetAll(serviceType);
        }

        private void AddBindings()
        {
            kernel.Bind<IMyBLL>().To<MyBLL>();
        }
    }
}

I use this to create a controller:

namespace MyNamespace.Controllers
{
    [Authorize]
    public class HomeController : Controller
    {
        private IMyBLL _myBLL;

        public HomeController(IMyBLL myBLLParam)
        {
            _myBLL = myBLLParam;
        }

        public PartialViewResult AddRecord()
        {
            return PartialView(new AddRecordViewModel());
        }

        [HttpPost]
        public void AddRecord(AddRecordViewModel recordViewModel)
        {
            var record = Mapper.Map<Record>(recordViewModel);

            _myBLL.AddRecord(record, User.Identity.Name);
        }
    }
}

Global.asax:

namespace MyNamespace.WebApplication
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            ApplicationUserManager.StartupAsync();
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AutoMapperWebConfiguration.Configure();
        }
    }
}

This calls the AutoMapper configuration:

namespace MyNamespace.WebApplication.Infrastructure
{
    public static class AutoMapperWebConfiguration
    {
        public static void Configure()
        {
            Mapper.Initialize(cfg => cfg.AddProfile(new RecordProfile()));
        }
    }

    public class RecordProfile : Profile
    {
        protected override void Configure()
        {
            Mapper.CreateMap<AddRecordViewModel, Record>().ReverseMap();
        }
    }
}

When I run this I get the following error message:

Missing type map configuration or unsupported mapping.

Mapping types:
AddRecordViewModel -> Record
 MyNamespace.WebApplication.ViewModels.Home.AddRecordViewModel -> MyNamespace.Model.Record

 Destination path:
 Record

 Source value:
 MyNamespace.WebApplication.ViewModels.Home.AddRecordViewModel

Do I miss something. It worked fine before I used the Ninject dependency resolver. Now it does not seem to find the mappings.


Edit:

If I add the Mapping Creation directly to the controller method it works:

[HttpPost]
public void AddRecord(AddRecordViewModel recordViewModel)
{
    Mapper.CreateMap<AddRecordViewModel, Record>().ReverseMap();
    var record = Mapper.Map<Record>(recordViewModel);

    _myBLL.AddRecord(record, User.Identity.Name);
}

The mapping itself and the models and view models do not seem to be the problem. I guess that the programm somehow does not find the mappings.

Even if I call the Auto Mapper Web Configuration in the controller method it works:

public void AddRecord(AddRecordViewModel recordViewModel)
{
    Infrastructure.AutoMapperWebConfiguration.Configure();

    var record = Mapper.Map<Record>(recordViewModel);

    _myBLL.AddRecord(record, User.Identity.Name);
}
Knives answered 23/1, 2015 at 22:3 Comment(6)
You defined an AddRecordViewModel -> Record but not the other way around. You need a second mapping for the other way.Timework
I now added the second mapping. Unfortunatelly I still get the same error message. It seems like the program does not find the mapping.Knives
Does your Record have any virtual property?Valeda
I have exactly this problem. I have other maps that work with the Queryable extensions (project to) but another map created continues to say there is no mapping even though the MapperConfiguration clearly creates a map for the two types. All in the same project running on the same machine. Please help!Backbreaker
Wow, I didn't know that mapperConfig.CreateMapper() was creating the ONLY instance that has the mappings! I have to use injection to get that mapper, I can't simply use Automapper.Mapper.Map...Backbreaker
@Knives I am also facing the same issue. Looks like program is not able to find the mapping. help me to figure out the solutionGoa
C
15

You need to add the reverse mapping also. You can do it one of two ways:

Mapper.CreateMap<AddRecordViewModel, Record>();
Mapper.CreateMap<Record, AddRecordViewModel>();

or in one go like so:

Mapper.CreateMap<AddRecordViewModel, Record>().ReverseMap();

The latter is preferable if you ask me.

Cullender answered 24/1, 2015 at 2:32 Comment(4)
Thanks for your anwser. I dit not know that you can add ReverseMap. That makes things cleaner. Unfortunately this was not the problem. I still get the same error message. I think that somehow the programm does not find the mapping. Can I somehow check durring runtime if the mapping exists?Knives
That's strange then. Could you post your the two classes so I can see the class members?Cullender
I do not think that it has something to do with the class members. When I add the Mapper.CreateMap Method directly to the controller method it works fine (see additional info in the main post). Only when I remove this and want to use the mapping via the Global.asax it does not work.Knives
Strange. Everything appears to be configured correctly. The error occurs when mapping the view model to the Record model. Does the mapping from the Record model to the view model work when your AutoMapper configuration left in Application_Start?Cullender
A
4

Don't call Mapper.CreateMap in your profile. Call base.CreateMap, and you're set:

public class RecordProfile : Profile
{
    protected override void Configure()
    {
        base.CreateMap<AddRecordViewModel, Record>().ReverseMap();
    }
}
Auckland answered 26/1, 2015 at 4:39 Comment(3)
Can you pls explain a bit?Valeda
how do you add a mapping for a list from the source to a flattened class?Randolphrandom
or just call CreateMap, base is implicit since CreateMap is defined in Profile.Cero
Z
1

Mapper.Initialize() should be used strictly once per solution.

If you call Initialize() somewhere later it will override all your previous mappings. Inspect your code attentively, guess, you'll find a call of this method in another place.

P.S.: That wasn't initial behavior of Automapper early, as I could see in pieces of code created 3 and more years ago on GitHub.

Zepeda answered 21/11, 2017 at 18:6 Comment(0)
T
0

I had a similar problem, I forgot to register in the Global.asax

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {


        AutoMapperConfig.RegisterMappings();

    }
}
Thomas answered 13/9, 2016 at 19:58 Comment(1)
actually I am going through test project and it's not getting mapping which i have done in AutoMapperConfig. Thanks Now it's workingSerle
J
0

In my case the problem was that some default Automapper mappings were registered with the IoC.

builder.Register(_ => AutomapperConfiguration.Configure()).As<IMapper>().SingleInstance();

The mapping that were failing were registered in a different place, the service configuration

static void Main(string[] args)
{
    var container = ConfigureDependencies();
    AutoMapping.Configure();

The project were was getting this error was a test project where the service configuration was not executed. When debugged had the illusion that the failing mappings were registered, as could see the ones from IoC mappings.

Solution, make sure all the mappings were registered in the test solution.

Jany answered 1/3, 2017 at 15:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.