144

Entity Model

public partial class Categoies
{
    public Categoies()
    {
        this.Posts = new HashSet<Posts>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public Nullable<int> PositionId { get; set; }

    public virtual CategoryPositions CategoryPositions { get; set; }
    public virtual ICollection<Posts> Posts { get; set; }
}

View Model

public class CategoriesViewModel
{
    public int Id { get; set; }

    [Required(ErrorMessage = "{0} alanı boş bırakılmamalıdır!")]
    [Display(Name = "Kategori Adı")]
    public string Name { get; set; }

    [Display(Name = "Kategori Açıklama")]
    public string Description { get; set; }

    [Display(Name = "Kategori Pozisyon")]
    [Required(ErrorMessage="{0} alanı boş bırakılmamalıdır!")]
    public int PositionId { get; set; }
}

CreateMap

Mapper.CreateMap<CategoriesViewModel, Categoies>()
            .ForMember(c => c.CategoryPositions, option => option.Ignore())
            .ForMember(c => c.Posts, option => option.Ignore());

Map

[HttpPost]
public ActionResult _EditCategory(CategoriesViewModel viewModel)
{
    using (NewsCMSEntities entity = new NewsCMSEntities())
    {
        if (ModelState.IsValid)
        {
            try
            {
                category = entity.Categoies.Find(viewModel.Id);
                AutoMapper.Mapper.Map<CategoriesViewModel, Categoies>(viewModel, category);
                //category = AutoMapper.Mapper.Map<CategoriesViewModel, Categoies>(viewModel);
                //AutoMapper.Mapper.Map(viewModel, category);
                entity.SaveChanges();

                // Veritabanı işlemleri başarılı ise yönlendirilecek sayfayı 
                // belirleyip ajax-post-success fonksiyonuna gönder.
                return Json(new { url = Url.Action("Index") });
            }
            catch (Exception ex)
            {

            }
        }

        // Veritabanı işlemleri başarısız ise modeli tekrar gönder.
        ViewBag.Positions = new SelectList(entity.CategoryPositions.ToList(), "Id", "Name");
        return PartialView(viewModel);
    }
}

Error

Missing type map configuration or unsupported mapping. Mapping types: CategoriesViewModel -> Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D NewsCMS.Areas.Admin.Models.CategoriesViewModel -> System.Data.Entity.DynamicProxies.Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D

Destination path: Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D

Source value: NewsCMS.Areas.Admin.Models.CategoriesViewModel

What am I missing? I try to find, but I cant see problem.

UPDATE

I have specified in application_start in Global.asax

protected void Application_Start()
{
    InitializeAutoMapper.Initialize();
}

InitializeClass

public static class InitializeAutoMapper
{
    public static void Initialize()
    {
        CreateModelsToViewModels();
        CreateViewModelsToModels();
    }

    private static void CreateModelsToViewModels()
    {
        Mapper.CreateMap<Categoies, CategoriesViewModel>();
    }

    private static void CreateViewModelsToModels()
    {
        Mapper.CreateMap<CategoriesViewModel, Categoies>()
            .ForMember(c => c.CategoryPositions, option => option.Ignore())
            .ForMember(c => c.Posts, option => option.Ignore());
    }
}
2
  • 2
    also Double check if you have same class name in different namespace. so there is a chance you are initializing different object and mapping and mapping different object Commented Jul 2, 2019 at 7:04
  • 1
    @Iman this was exactly my problem today, pretty well hidden in a gazillion mappings. Commented Oct 24, 2021 at 20:53

17 Answers 17

87

Where have you specified the mapping code (CreateMap)? Reference: Where do I configure AutoMapper?

If you're using the static Mapper method, configuration should only happen once per AppDomain. That means the best place to put the configuration code is in application startup, such as the Global.asax file for ASP.NET applications.

If the configuration isn't registered before calling the Map method, you will receive Missing type map configuration or unsupported mapping.

Sign up to request clarification or add additional context in comments.

1 Comment

yes you have to register your class Mapper.CreateMap<IDataReader, UserBo>();
51

In your class AutoMapper profile, you need to create a map for your entity and viewmodel.

ViewModel To Domain Model Mappings:

This is usually in AutoMapper/DomainToViewModelMappingProfile

In Configure(), add a line like

Mapper.CreateMap<YourEntityViewModel, YourEntity>();

Domain Model To ViewModel Mappings:

In ViewModelToDomainMappingProfile, add:

Mapper.CreateMap<YourEntity, YourEntityViewModel>();

Gist example

2 Comments

Thank you :) I had been sleeping and thought it just worked both ways, and didn't really realize that ordering was important. Profile.CreateMap<TSource,TDestination>()
@Kiksen Mapper.CreateMap<YourEntityViewModel, YourEntity>().ReverseMap(); .ReverseMap() will make it work both ways and you don't even have to worry about the order in that case.
26

Notice the Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D class in the exception? That's an Entity Framework proxy. I would recommend you disposing of your EF context to ensure that all your objects are eagerly loaded from the database and no such proxies exist:

[HttpPost]
public ActionResult _EditCategory(CategoriesViewModel viewModel)
{
    Categoies category = null;
    using (var ctx = new MyentityFrameworkContext())
    {
        category = ctx.Categoies.Find(viewModel.Id);
    }
    AutoMapper.Mapper.Map<CategoriesViewModel, Categoies>(viewModel, category);
    //category = AutoMapper.Mapper.Map<CategoriesViewModel, Categoies>(viewModel, category);
    entity.SaveChanges();
}

If the entity retrieval is performed inside a data access layer (which of course is the correct way) make sure you dispose your EF context before returning instances from your DAL.

4 Comments

Is this done automatically, or do we need to let Automapper know what it has to map ( which is anything but auto)?
You need to configure the mappings. And for those that you want custom mapping rules, write those rules.
Thankyou. I had completely skipped over the section on the automapper how to..somehow.
Its correct , Actually we have to create Map for Get and Post of Edit Method , for Get Its: Domain Model To ViewModel Mappings and for Post Its: ViewModel To Domain Model Mappings , check this, hope helps someone.
26

I was trying to map an IEnumerable to an object. This is way I got this error. Maybe it helps.

2 Comments

This comment helped me
This comment helped me +1
9

I did this to remove the error:

Mapper.CreateMap<FacebookUser, ProspectModel>();
prospect = Mapper.Map(prospectFromDb, prospect);

Comments

8

I had same issue in .Net Core. Because my base dto class(i give it as a type in startup for automapper assembly) was in different project. Automapper tried to search for profiles in base class project. But my dto's were in different project. I moved my base class. And problem solved. This may help for some persons.

Comments

7

I found the solution, Thanks all for reply.

category = (Categoies)AutoMapper.Mapper.Map(viewModel, category, typeof(CategoriesViewModel), typeof(Categories));

But, I have already dont know the reason. I cant understand fully.

2 Comments

Did you find the cause of the problem?
Maybe it's that typo "Categoies"
6

Check your Global.asax.cs file and be sure that this line be there

 AutoMapperConfig.Configure();

Comments

6

In my case, I had created the map, but was missing the ReverseMap function. Adding it got rid of the error.

      private static void RegisterServices(ContainerBuilder bldr)
      {
         var config = new MapperConfiguration(cfg =>
         {
            cfg.AddProfile(new CampMappingProfile());
         });
         ...
       }


      public CampMappingProfile()
      {
         CreateMap<Talk, TalkModel>().ReverseMap();
         ...
      }

Comments

4

I know this is a rather old question as of now, but I had found the proper solution was that I was not declaring the assembly attribute.

My code is:

using AutoMapper;
...

namespace [...].Controllers
{
    public class HousingTenureTypesController : LookupController<HousingTenureType, LookupTypeModel>
    {
        Mapper.CreateMap<HousingTenureType, LookupTypeModel>().ReverseMap();
    }
    ...
}

This was fixed by adding the following line before my namespace declaration:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(HousingTenureTypesController), "AutoMapperStart")]

The full code is:

using AutoMapper;
...

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(HousingTenureTypesController), "AutoMapperStart")]

namespace [...].Controllers
{
    public class HousingTenureTypesController : LookupController<HousingTenureType, LookupTypeModel>
    {
        Mapper.CreateMap<HousingTenureType, LookupTypeModel>().ReverseMap();
    }
    ...
}

Comments

2

We got the same error after updating from AutoMapper v.3 to v.5.

And eventually we have found that destination class has Property with the type IDictionary<string, object> and at the same type Profile mapping was valid.

There were next possible solutions:

  1. To update to higher version. In the v.6 the bug dissapeared.
  2. Or to ignore that prop in the mapping.
  3. Or to use method Mapper.Map<IFooDto>(foo) instead of Mapper.Map(foo, fooDto).

Our profile was like that using interface as destination:

public class FooProfile : Profile
{
    public FooProfile()
    {
        CreateMap<Foo, IFooDto>()
            .ConstructUsing(foo => new FooDto());
    }
}

Also I should mention that during update from v.3 to higher versions we have met many bugs and differences comparing with old versions and what helped us:

  • Every time to check that maybe next version will fix the bug;
  • Double check existing Mapping configuration. It can have old hidden bugs like mapping to property without a setter or existing duplicated mapping and so on. And it can be that old versions allows this, new does not.

Comments

1

In my case the data type of some of the properties of Dto was different than model class. For example, in my InsertUserDto class, the data type of email was "string" while in User class it was "EmailAddressAttribute" and data type of DateOfBirth was "DateTime" in InsertUserDto class and the data type of DateOfBirth was "DateOnly" in User class. Try matching all the data types of each class.

Program.cs:

IMapper mapper = MappingConfig.RegisterMaps().CreateMapper();
builder.Services.AddSingleton(mapper);
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

Automapper.cs:

public class MappingConfig
{
    public static MapperConfiguration RegisterMaps()
    {
        var mappingConfig = new MapperConfiguration(config =>
        {
            config.CreateMap<InsertUserDto, Users>()
            .ForMember(dest => dest.user_id, option => option.Ignore())
            .ForMember(dest => dest.user_guid, option => option.Ignore())
            .ForMember(dest => dest.created_date, option => option.Ignore())
            .ForMember(dest => dest.updated_date, option => option.Ignore())
            .ForMember(dest => dest.status, option => option.Ignore())
            .ForMember(dest => dest.address_id, option => option.Ignore());
            config.CreateMap<Users, InsertUserDto>();
        });
        return mappingConfig;
    }
}

Comments

0

Upgrade Automapper to version 6.2.2. It helped me

Comments

0

I have solved it hope it helps you :33

For the same type you have to use:

[AutoMap(typeof(UserInfoView))]

[AutoMap(typeof(UserInfoView))]

Comments

0

From your API controller, it is possible to have an object that resembles a Data Transfer Object (DTO), but is not the actual DTO. In scenarios where different requests for Create, Update, and Delete operations are present, it may be necessary to convert the request without using an Automapping Profile in C#.

    public class CustomerProfile : Profile
{
    public CustomerProfile()
    {
        CreateMap<Customer, CustomerDto>();
    }
}

If that is the case, utilizing a single Data Transfer Object (DTO) for all operations may not be sufficient as the request passed to the controller may be specific to a particular operation. In such instances, it is necessary to include additional request objects.

public class CustomerProfile : Profile
{
    public CustomerProfile()
    {
        CreateMap<Customer, CustomerDto>();
        CreateMap<CustomerDto, Customer>();
        CreateMap<CreateCustomerRequest, Customer>();
        CreateMap<UpdateCustomerRequest, Customer>();
        CreateMap<DeleteCustomerRequest, Customer>();
    }
}

Comments

-2

I created a new AutomapperProfile class. It extends Profile. We have over 100 projects in our solution. Many projects have an AutomapperProfile class, but this one was new to this existing project. However, I did find what I had to do to fix this issue for us. There is a Binding project. Within the Initialization there is this code:

var mappingConfig = new List<Action<IConfiguration>>();

// Initialize the Automapper Configuration for all Known Assemblies
mappingConfig.AddRange( new List<Action<IConfiguration>>
{
   ConfigureProfilesInAssemblyOfType<Application.Administration.AutomapperProfile>,
   //...

I had to add ConfigureProfilesInAssemblyOfType<MyNewNamespace.AutomapperProfile>

Note that ConfigureProfilesInAssemblyOfType looks like this:

    private static void ConfigureProfilesInAssemblyOfType<T>( IConfiguration configuration )
    {
        var log = LogProvider.Get( typeof (AutomapperConfiguration) );

        // The Automapper Profile Type
        var automapperProfileType = typeof (Profile);

        // The Assembly containing the type
        var assembly = typeof (T).Assembly;
        log.Debug( "Scanning " + assembly.FullName );

        // Configure any Profile classes found in the assembly containing the type.
        assembly.GetTypes()
            .Where( automapperProfileType.IsAssignableFrom ).ToList()
            .ForEach( x =>
            {
                log.Debug( "Adding Profile '" + x.FullName + "'" );
                configuration.AddProfile( Activator.CreateInstance( x ) as Profile );
            } );
    }

Best regards, -Jeff

Comments

-2

For .net core with dependency injection I made it work in that way:

builder.Services.AddAutoMapper(config =>
{
    config.CreateMap<CaseModel, Case>();
    config.CreateMap<Case, CaseModel>();
}, AppDomain.CurrentDomain.GetAssemblies());

In that case each instance of mapper with have this mapping configuration.

Mapper user class:

public CaseController(ICaseHttpClient caseHttpClient, IMapper mapper)
{
    _caseHttpClient = caseHttpClient;
    _mapper = mapper;
}

  [HttpGet("{id}")]
        public async Task<ActionResult<CaseModel>> GetById(string id)
        {
            var caseResult = await _caseHttpClient.GetCase(id);
            var caseModelMapped = _mapper.Map<CaseModel>(caseResult);
            return Ok(caseModelMapped);
        }

I hope it helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.