Automapper缺少类型映射配置或不支持的映射-错误


81

实体模型

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

查看模型

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

创建地图

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

地图

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

错误

缺少类型映射配置或不支持的映射。映射类型:CategoriesViewModel-> Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D NewsCMS.Areas.Admin.Models.categoryViewModel-> System.Data.Entity.DynamicProxies.Categoies_7314E98C41152985A4218174DF4

目标路径:Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D

源值:NewsCMS.Areas.Admin.Models.CategoriesViewModel

我想念什么?我尝试查找,但是看不到问题。

更新

我已经在Global.asax的application_start中指定了

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

还要仔细检查您在不同名称空间中是否具有相同的类名。因此,您有可能初始化不同的对象并映射和映射不同的对象
Iman

Answers:


66

您在哪里指定了映射代码(CreateMap)?参考:在哪里配置AutoMapper?

如果您使用静态Mapper方法,则每个AppDomain只能进行一次配置。这意味着放置配置代码的最佳位置是在应用程序启动中,例如ASP.NET应用程序的Global.asax文件。

如果在调用Map方法之前未注册配置,您将收到 Missing type map configuration or unsupported mapping.


2
是的,您必须注册您的类Mapper.CreateMap <IDataReader,UserBo>();。
Nikki

32

在您的类AutoMapper配置文件中,您需要为您的实体和视图模型创建一个映射。

ViewModel到域模型的映射:

通常在 AutoMapper/DomainToViewModelMappingProfile

在中Configure(),添加一行

Mapper.CreateMap<YourEntityViewModel, YourEntity>();

域模型到ViewModel的映射:

在中ViewModelToDomainMappingProfile,添加:

Mapper.CreateMap<YourEntity, YourEntityViewModel>();

要点示例


1
谢谢:)我一直在睡觉,以为它既可以双向工作,也没有真正意识到订购很重要。Profile.CreateMap <TSource,TDestination>()
Kiksen

3
@Kiksen .ReverseMap Mapper.CreateMap<YourEntityViewModel, YourEntity>().ReverseMap(); ()可以使其双向工作,在这种情况下,您甚至不必担心顺序。
Pramil Gawande

20

注意Categoies_7314E98C41152985A4218174DDDF658046BC82AB0ED9E1F0440514D79052F84D异常中的类吗?那是一个实体框架代理。我建议您处置EF上下文,以确保从数据库中急切地加载所有对象,并且不存在此类代理:

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

如果实体检索是在数据访问层内执行的(这当然是正确的方法),请确保在从DAL返回实例之前先布置EF上下文。


这是自动完成的,还是我们需要让Automapper知道必须映射的内容(除了auto以外,什么都没有)?
brumScouse

1
您需要配置映射。对于需要自定义映射规则的规则,请编写这些规则。
Darin Dimitrov 2013年

谢谢。我已经完全跳过了有关自动映射器的部分。
brumScouse

它是正确的,实际上我们必须为Get方法和Post编辑方法创建Map,以便将其:域模型映射到ViewModel映射,并将其:将ViewModel映射到域模型映射,选中此项,希望对您有所帮助。
shaijut

7

我这样做是为了消除错误:

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

5

我找到了解决方案,谢谢大家的答复。

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

但是,我已经不知道原因了。我无法完全理解。


您找到问题的原因了吗?
土星科技

16
也许就是错字“类别”
Joe Phillips

5

检查您的Global.asax.cs文件,并确保此行存在

 AutoMapperConfig.Configure();

2

我知道到目前为止这是一个相当老的问题,但是我发现正确的解决方案是我没有声明Assembly属性。

我的代码是:

using AutoMapper;
...

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

通过在命名空间声明之前添加以下行来解决此问题:

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

完整的代码是:

using AutoMapper;
...

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

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

2

我在.Net Core中有同样的问题。因为我的基本dto类(我在启动时将其作为自动映射器程序集的一种类型)在其他项目中。Automapper试图在基类项目中搜索配置文件。但是我的dto在不同的项目中。我搬了我的基础班。问题解决了。这可能对某些人有帮助。


1

就我而言,我已经创建了地图,但是缺少了ReverseMap函数。添加它摆脱了错误。

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


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

1

我试图将IEnumerable映射到对象。这是我收到此错误的方法。也许有帮助。



-1

我创建了一个新的AutomapperProfile类。它扩展了Profile。我们的解决方案中有100多个项目。许多项目都有一个AutomapperProfile类,但这是该现有项目的新功能。但是,我确实找到了为我们解决此问题所必须做的事情。有一个绑定项目。在初始化中有以下代码:

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

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

我必须添加ConfigureProfilesInAssemblyOfType < MyNewNamespace .AutomapperProfile>

请注意,ConfigureProfilesInAssemblyOfType看起来像这样:

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

最好的问候,-杰夫

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.