Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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);
}
like image 566
Alexander Avatar asked Jan 23 '15 22:01

Alexander


People also ask

How do I use AutoMapper in .NET core?

AutoMapper Mapping ProfileTo create a mapping profile, create a class that derives from AutoMapper Profile class. Use CreateMap method to create a mapping from one type to another. CreateMap method is called twice to create 2 mappings. Employee to EditEmployeeModel and the reverse.

What is AutoMapper in .NET core?

AutoMapper is a simple library that helps us to transform one object type into another. It is a convention-based object-to-object mapper that requires very little configuration. The object-to-object mapping works by transforming an input object of one type into an output object of a different type.

How does AutoMapper work in C#?

AutoMapper in C# is a library used to map data from one object to another. It acts as a mapper between two objects and transforms one object type into another. It converts the input object of one type to the output object of another type until the latter type follows or maintains the conventions of AutoMapper.


2 Answers

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.

like image 112
Joseph Woodward Avatar answered Oct 23 '22 14:10

Joseph Woodward


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.

like image 41
rock_walker Avatar answered Oct 23 '22 15:10

rock_walker