10
votes

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);
}
5
You defined an AddRecordViewModel -> Record but not the other way around. You need a second mapping for the other way. - Erik Funkenbusch
I now added the second mapping. Unfortunatelly I still get the same error message. It seems like the program does not find the mapping. - Alexander
Does your Record have any virtual property? - Blaise
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! - Skychan
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... - Skychan

5 Answers

15
votes

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.

4
votes

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();
    }
}
1
votes

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.

0
votes

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();

    }
}
0
votes

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.