Automapper fehlende Typzuordnungskonfiguration oder nicht unterstützte Zuordnung - Fehler


80

Entitätsmodell

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

Modell anzeigen

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

Karte

[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

Fehlende Typzuordnungskonfiguration oder nicht unterstützte Zuordnung. Mapping-Typen: CategoriesViewModel -> Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D NewsCMS.Areas.Admin.Models.CategoriesViewModel -> System.Data.Entity.DynamicProxies.Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D

Zielpfad: Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D

Quellwert: NewsCMS.Areas.Admin.Models.CategoriesViewModel

Was vermisse ich? Ich versuche zu finden, aber ich kann kein Problem sehen.

AKTUALISIEREN

Ich habe in application_start in Global.asax angegeben

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

Überprüfen Sie außerdem, ob Sie denselben Klassennamen in einem anderen Namespace haben. Es besteht also die Möglichkeit, dass Sie ein anderes Objekt initialisieren und ein anderes Objekt zuordnen und zuordnen
Iman

Antworten:


66

Wo haben Sie den Mapping-Code (CreateMap) angegeben? Referenz: Wo konfiguriere ich AutoMapper?

Wenn Sie die statische Mapper-Methode verwenden, sollte die Konfiguration nur einmal pro AppDomain erfolgen. Das bedeutet, dass der Konfigurationscode am besten beim Starten der Anwendung platziert werden kann, z. B. in der Datei Global.asax für ASP.NET-Anwendungen.

Wenn die Konfiguration vor dem Aufrufen der Map-Methode nicht registriert wurde, erhalten Sie Missing type map configuration or unsupported mapping.


2
Ja, Sie müssen Ihre Klasse Mapper.CreateMap <IDataReader, UserBo> () registrieren.
Nikki

32

In Ihrem Klassenprofil AutoMappermüssen Sie eine Karte für Ihre Entität und Ihr Ansichtsmodell erstellen.

Zuordnungen von ViewModel zu Domänenmodellen:

Dies ist in der Regel in AutoMapper/DomainToViewModelMappingProfile

In Configure(), fügen Sie eine Zeile wie

Mapper.CreateMap<YourEntityViewModel, YourEntity>();

Domänenmodell für ViewModel-Zuordnungen:

In ViewModelToDomainMappingProfilehinzufügen:

Mapper.CreateMap<YourEntity, YourEntityViewModel>();

Kernbeispiel


1
Danke :) Ich hatte geschlafen und dachte, es funktioniert einfach in beide Richtungen und wusste nicht wirklich, dass die Bestellung wichtig ist. Profile.CreateMap <TSource, TDestination> ()
Kiksen

3
@Kiksen Mapper.CreateMap<YourEntityViewModel, YourEntity>().ReverseMap(); .ReverseMap () funktioniert in beide Richtungen und Sie müssen sich in diesem Fall nicht einmal um die Reihenfolge kümmern.
Pramil Gawande

20

Beachten Sie die Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84DKlasse in der Ausnahme? Das ist ein Entity Framework-Proxy. Ich würde Ihnen empfehlen, Ihren EF-Kontext zu entsorgen, um sicherzustellen, dass alle Ihre Objekte eifrig aus der Datenbank geladen werden und keine solchen Proxys vorhanden sind:

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

Wenn der Entitätsabruf innerhalb einer Datenzugriffsschicht durchgeführt wird (was natürlich der richtige Weg ist), stellen Sie sicher, dass Sie Ihren EF-Kontext entsorgen, bevor Sie Instanzen von Ihrem DAL zurückgeben.


Wird dies automatisch durchgeführt oder müssen wir Automapper wissen lassen, was zuzuordnen ist (was alles andere als automatisch ist)?
brumScouse

1
Sie müssen die Zuordnungen konfigurieren. Und für diejenigen, die benutzerdefinierte Zuordnungsregeln wünschen, schreiben Sie diese Regeln.
Darin Dimitrov

Danke. Ich hatte den Abschnitt über den Automapper komplett übersprungen, wie man ... irgendwie.
brumScouse

Es ist richtig. Eigentlich müssen wir eine Karte für die Get- und Post-of-Edit-Methode erstellen , für Get Its: Domain Model To ViewModel Mappings und für Post Its: ViewModel To Domain Model Mappings. Überprüfen Sie dies , hoffen Sie, dass jemand hilft.
Shaijut

7

Ich habe dies getan, um den Fehler zu beheben:

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

5

Ich habe die Lösung gefunden. Vielen Dank für die Antwort.

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

Aber ich kenne den Grund schon nicht. Ich kann es nicht ganz verstehen.


Haben Sie die Ursache des Problems gefunden?
Saturn Technologies

16
Vielleicht ist es dieser Tippfehler "Categoies"
Joe Phillips

5

Überprüfen Sie Ihre Global.asax.cs-Datei und stellen Sie sicher, dass diese Zeile vorhanden ist

 AutoMapperConfig.Configure();

2

Ich weiß, dass dies derzeit eine ziemlich alte Frage ist, aber ich hatte die richtige Lösung gefunden, indem ich das Assembly-Attribut nicht deklarierte.

Mein Code lautet:

using AutoMapper;
...

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

Dies wurde behoben, indem die folgende Zeile vor meiner Namespace-Deklaration hinzugefügt wurde:

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

Der vollständige Code lautet:

using AutoMapper;
...

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

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

2

Ich hatte das gleiche Problem in .Net Core. Weil meine Basis-dto-Klasse (ich gebe sie als Starttyp für die Automapper-Montage an) in einem anderen Projekt war. Automapper hat versucht, im Basisklassenprojekt nach Profilen zu suchen. Aber meine Dto's waren in einem anderen Projekt. Ich habe meine Basisklasse verschoben. Und Problem gelöst. Dies kann für einige Personen hilfreich sein.


1

In meinem Fall hatte ich die Karte erstellt, aber die ReverseMap-Funktion fehlte. Durch Hinzufügen wurde der Fehler behoben.

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


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

1

Ich habe versucht, einem Objekt eine IEnumerable zuzuordnen. Auf diese Weise habe ich diesen Fehler erhalten. Vielleicht hilft es.


-1

Aktualisieren Sie Automapper auf Version 6.2.2. Es hat mir geholfen


-1

Ich habe eine neue AutomapperProfile-Klasse erstellt. Es erweitert das Profil. Wir haben über 100 Projekte in unserer Lösung. Viele Projekte haben eine AutomapperProfile-Klasse, aber diese war neu in diesem bestehenden Projekt. Ich habe jedoch herausgefunden, was ich tun muss, um dieses Problem für uns zu beheben. Es gibt ein Bindungsprojekt. Innerhalb der Initialisierung gibt es diesen 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>,
   //...

Ich musste ConfigureProfilesInAssemblyOfType < MyNewNamespace .AutomapperProfile> hinzufügen

Beachten Sie, dass ConfigureProfilesInAssemblyOfType folgendermaßen aussieht:

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

Viele Grüße, -Jeff

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.