Automapper falta la configuración del mapa de tipo o la asignación no es compatible - Error


81

Modelo de entidad

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; }
}

Ver modelo

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

Mapa

[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

Falta la configuración del mapa de tipo o la asignación no es compatible. Tipos de mapeo: CategoriesViewModel -> Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D NewsCMS.Areas.Admin.Models.CategoriesViewModel -> System.Data.Entity.DynamicProxies475429.Cate1D8D82AB0ED9E1F0440514C

Ruta de destino: Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D

Valor de fuente: NewsCMS.Areas.Admin.Models.CategoriesViewModel

¿Qué me estoy perdiendo? Intento encontrar, pero no veo el problema.

ACTUALIZAR

He especificado en application_start en 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());
    }
}

También verifique si tiene el mismo nombre de clase en un espacio de nombres diferente. por lo que existe la posibilidad de que esté inicializando un objeto diferente y mapeando y mapeando un objeto diferente
Iman

Respuestas:


66

¿Dónde ha especificado el código de mapeo (CreateMap)? Referencia: ¿Dónde configuro AutoMapper?

Si está utilizando el método Mapper estático, la configuración solo debería ocurrir una vez por AppDomain. Eso significa que el mejor lugar para colocar el código de configuración es el inicio de la aplicación, como el archivo Global.asax para aplicaciones ASP.NET.

Si la configuración no está registrada antes de llamar al método Map, recibirá Missing type map configuration or unsupported mapping.


2
sí, tienes que registrar tu clase Mapper.CreateMap <IDataReader, UserBo> ();
Nikki

32

En su AutoMapperperfil de clase , debe crear un mapa para su entidad y modelo de vista.

Asignaciones de modelo de vista a modelo de dominio:

Esto suele estar en AutoMapper/DomainToViewModelMappingProfile

En Configure(), agregue una línea como

Mapper.CreateMap<YourEntityViewModel, YourEntity>();

Modelo de dominio para mapeos ViewModel:

En ViewModelToDomainMappingProfile, agregue:

Mapper.CreateMap<YourEntity, YourEntityViewModel>();

Ejemplo de esencia


1
Gracias :) Había estado durmiendo y pensé que funcionaba en ambos sentidos, y realmente no me di cuenta de que ordenar era importante. Profile.CreateMap <TSource, TDestination> ()
Kiksen

3
@Kiksen Mapper.CreateMap<YourEntityViewModel, YourEntity>().ReverseMap(); .ReverseMap () hará que funcione en ambos sentidos y ni siquiera tendrá que preocuparse por el orden en ese caso.
Pramil Gawande

20

¿Observa la Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84Dclase en la excepción? Eso es un proxy de Entity Framework. Le recomendaría que se deshaga de su contexto EF para asegurarse de que todos sus objetos se carguen con entusiasmo desde la base de datos y no existan tales proxies:

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

Si la recuperación de la entidad se realiza dentro de una capa de acceso a datos (que, por supuesto, es la forma correcta), asegúrese de eliminar su contexto EF antes de devolver instancias de su DAL.


¿Esto se hace automáticamente o debemos informar a Automapper qué tiene que mapear (que es cualquier cosa menos automático)?
brumScouse

1
Necesita configurar las asignaciones. Y para aquellos que quieran reglas de mapeo personalizadas, escríbalas.
Darin Dimitrov

Gracias. Me había saltado completamente la sección sobre el automapper cómo ... de alguna manera.
brumScouse

Es correcto, en realidad tenemos que crear un mapa para obtener y publicar el método de edición , para obtener su: modelo de dominio a asignaciones de modelo de vista y para publicar su: asignaciones de modelo de vista a modelo de dominio, verifique esto , espero que ayude a alguien.
shaijut

7

Hice esto para eliminar el error:

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

5

Encontré la solución, gracias a todos por responder.

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

Pero ya no sé el motivo. No puedo entender completamente.


¿Encontraste la causa del problema?
Saturn Technologies

16
Tal vez sea ese error tipográfico "Categoies"
Joe Phillips

5

Verifique su archivo Global.asax.cs y asegúrese de que esta línea esté allí

 AutoMapperConfig.Configure();

2

Sé que esta es una pregunta bastante antigua a partir de ahora, pero encontré que la solución adecuada era que no estaba declarando el atributo de ensamblaje.

Mi codigo es:

using AutoMapper;
...

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

Esto se solucionó agregando la siguiente línea antes de mi declaración de espacio de nombres:

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

El código completo es:

using AutoMapper;
...

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

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

2

Tuve el mismo problema en .Net Core. Porque mi clase base dto (la doy como un tipo en el inicio para el ensamblaje de automapper) estaba en un proyecto diferente. Automapper intentó buscar perfiles en el proyecto de clase base. Pero mis dto estaban en un proyecto diferente. Moví mi clase base. Y problema resuelto. Esto puede ayudar a algunas personas.


1

En mi caso, había creado el mapa, pero faltaba la función ReverseMap. Agregarlo eliminó el error.

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


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

1

Estaba intentando mapear un IEnumerable a un objeto. Así es como recibí este error. Quizás ayude.


-1

Actualice Automapper a la versión 6.2.2. Me ayudó


-1

Creé una nueva clase de AutomapperProfile. Extiende Perfil. Tenemos más de 100 proyectos en nuestra solución. Muchos proyectos tienen una clase AutomapperProfile, pero esta era nueva en este proyecto existente. Sin embargo, encontré lo que tenía que hacer para solucionar este problema. Hay un proyecto vinculante. Dentro de la inicialización hay este código:

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

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

Tuve que agregar ConfigureProfilesInAssemblyOfType < MyNewNamespace .AutomapperProfile>

Tenga en cuenta que ConfigureProfilesInAssemblyOfType se ve así:

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

Saludos cordiales, -Jeff

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.