Automapper brak konfiguracji mapy typu lub nieobsługiwane mapowanie - błąd

86

Model jednostki

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

Wyświetl 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());

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

Błąd

Brak konfiguracji mapy typu lub nieobsługiwane mapowanie. Typy odwzorowań: CategoriesViewModel -> Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D NewsCMS.Areas.Admin.Models.CategoriesViewModel -> System.Data.Entity.DynamicProxies14F0440514D79052F84D NewsCMS.Areas.Admin.

Ścieżka docelowa: Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D

Wartość źródłowa: NewsCMS.Areas.Admin.Models.CategoriesViewModel

czego mi brakuje? Próbuję znaleźć, ale nie widzę problemu.

AKTUALIZACJA

Podałem w application_start w 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());
    }
}
AliRıza Adıyahşi
źródło
również dwukrotnie sprawdź, czy masz tę samą nazwę klasy w innej przestrzeni nazw. więc jest szansa, że ​​inicjalizujesz inny obiekt i mapujesz i mapujesz inny obiekt
Iman

Odpowiedzi:

66

Gdzie określiłeś kod mapowania (CreateMap)? Odniesienie: Gdzie mogę skonfigurować AutoMapper?

Jeśli używasz statycznej metody Mapper, konfiguracja powinna nastąpić tylko raz na AppDomain. Oznacza to, że najlepszym miejscem na umieszczenie kodu konfiguracyjnego jest uruchamianie aplikacji, na przykład plik Global.asax dla aplikacji ASP.NET.

Jeśli konfiguracja nie zostanie zarejestrowana przed wywołaniem metody Map, otrzymasz plik Missing type map configuration or unsupported mapping.

Martin4ndersen
źródło
2
tak, musisz zarejestrować swoją klasę Mapper.CreateMap <IDataReader, UserBo> ();
Nikki
35

W AutoMapperprofilu klasy musisz utworzyć mapę dla swojej encji i modelu widoku.

Mapowanie modelu widoku do modelu domeny:

Zwykle jest to AutoMapper/DomainToViewModelMappingProfile

W Configure(), dodaj linię taką jak

Mapper.CreateMap<YourEntityViewModel, YourEntity>();

Model domeny do wyświetlenia Odwzorowania modelu:

W ViewModelToDomainMappingProfile, dodaj:

Mapper.CreateMap<YourEntity, YourEntityViewModel>();

Przykład streszczenia

Pierry
źródło
1
Dziękuję :) Spałem i myślałem, że to działa w obie strony i nie zdawałem sobie sprawy, że zamawianie jest ważne. Profile.CreateMap <TSource, TDestination> ()
Kiksen
4
@Kiksen Mapper.CreateMap<YourEntityViewModel, YourEntity>().ReverseMap(); .ReverseMap () sprawi, że będzie działać w obie strony i nie musisz się nawet martwić o kolejność w tym przypadku.
Pramil Gawande
20

Zwróć uwagę na Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84Dklasę w wyjątku? To jest serwer proxy Entity Framework. Zalecałbym pozbycie się kontekstu EF, aby upewnić się, że wszystkie obiekty są chętnie ładowane z bazy danych i nie istnieją takie serwery proxy:

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

Jeśli pobieranie jednostki jest wykonywane w warstwie dostępu do danych (co oczywiście jest poprawnym sposobem), upewnij się, że usunąłeś kontekst EF przed zwróceniem wystąpień z DAL.

Darin Dimitrov
źródło
Czy dzieje się to automatycznie, czy też musimy pozwolić Automapperowi wiedzieć, co ma mapować (co nie jest automatyczne)?
brumScouse
1
Musisz skonfigurować mapowania. A dla tych, którzy chcą niestandardowych reguł mapowania, napisz te reguły.
Darin Dimitrov
Dziękuję Ci. Całkowicie przeskoczyłem przez sekcję dotyczącą automappera, jak ... jakoś.
brumScouse
To prawda, właściwie musimy utworzyć mapę do pobierania i wysyłania metody edycji , aby uzyskać: model domeny do widoku mapowania modelu i opublikować: mapowanie modelu widoku do modelu domeny, sprawdź to , nadzieja komuś pomoże.
Shaiju T
7

Zrobiłem to, aby usunąć błąd:

Mapper.CreateMap<FacebookUser, ProspectModel>();
prospect = Mapper.Map(prospectFromDb, prospect);
Sanchitos
źródło
5

Znalazłem rozwiązanie, dziękuję wszystkim za odpowiedź.

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

Ale ja już nie znam powodu. Nie mogę w pełni zrozumieć.

AliRıza Adıyahşi
źródło
Czy znalazłeś przyczynę problemu?
Saturn Technologies,
16
Może to ta literówka „Categoies”
Joe Phillips
5

Sprawdź swój plik Global.asax.cs i upewnij się, że jest tam ten wiersz

 AutoMapperConfig.Configure();
neustart47
źródło
3

Miałem ten sam problem w .Net Core. Ponieważ moja podstawowa klasa dto (podaję ją jako typ podczas uruchamiania dla zespołu automapper) była w innym projekcie. Automapper próbował wyszukiwać profile w projekcie klasy bazowej. Ale moje dto były w innym projekcie. Przeniosłem swoją klasę podstawową. I problem rozwiązany. Może to pomóc niektórym osobom.

deweloper
źródło
2

Wiem, że na razie jest to dość stare pytanie, ale znalazłem właściwe rozwiązanie, ponieważ nie deklarowałem atrybutu assemblera.

Mój kod to:

using AutoMapper;
...

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

Zostało to naprawione przez dodanie następującego wiersza przed moją deklaracją przestrzeni nazw:

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

Pełny kod to:

using AutoMapper;
...

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

namespace [...].Controllers
{
    public class HousingTenureTypesController : LookupController<HousingTenureType, LookupTypeModel>
    {
        Mapper.CreateMap<HousingTenureType, LookupTypeModel>().ReverseMap();
    }
    ...
}
Mitchell Schwitzer
źródło
1

W moim przypadku utworzyłem mapę, ale brakowało jej funkcji ReverseMap. Dodanie go pozbyło się błędu.

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


      public CampMappingProfile()
      {
         CreateMap<Talk, TalkModel>().ReverseMap();
         ...
      }
miłość na żywo
źródło
1

Próbowałem zmapować IEnumerable do obiektu. W ten sposób otrzymałem ten błąd. Może to pomaga.

user3542654
źródło
-1

Zaktualizuj Automapper do wersji 6.2.2. Pomogło mi

Anand
źródło
-1

Utworzyłem nową klasę AutomapperProfile. Rozszerza profil. W naszym rozwiązaniu mamy ponad 100 projektów. Wiele projektów ma klasę AutomapperProfile, ale ta była nowością w istniejącym projekcie. Jednak znalazłem to, co muszę zrobić, aby rozwiązać ten problem. Istnieje projekt wiążący. W ramach inicjalizacji znajduje się następujący kod:

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

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

Musiałem dodać ConfigureProfilesInAssemblyOfType < MyNewNamespace .AutomapperProfile>

Zauważ, że ConfigureProfilesInAssemblyOfType wygląda następująco:

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

Pozdrawiam, Jeff

Waldron
źródło