AutoMapper错误地映射了名为Type的属性-如何处理多个类

本文关键字:何处理 处理 属性 映射 错误 Type AutoMapper | 更新日期: 2023-09-27 18:16:04

在用AutoMapper映射对象时,我们意识到,如果类中有一个名为Type的属性,并且没有定义显式映射,AutoMapper会将该属性映射到源类型的Type name

为了演示,假设我有以下类

public class SoldierDTO
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Category { get; set; }        
}
public class Officer
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string BaseGroup { get; set; }
    public DateTime ActiveFrom { get; set; }
    public string Type { get; set; }
}

然后我定义了映射(Type没有映射(

Mapper.CreateMap<SoldierDTO, Officer>()
    .ForMember(dest => dest.BaseGroup, opt => opt.MapFrom(src => src.Category))
    .ForMember(dest => dest.ActiveFrom, opt => opt.UseValue(DateTime.Now));
    //.ForMember(dest => dest.Type, opt => opt.Ignore()); //this works though

让我们用绘制一个简单的士兵对象

var soldier = new SoldierDTO { Id = 11, Name = "Rackham", Category = "Gunner" };
var officer = Mapper.Map<Officer>(soldier); //Type = "Entities.SoldierDTO"

一切都很好,只是Type属性被分配了一个字符串值"Entities.SoldierDTO",它只是源类型的全名!我可以看到GitHub上有一个已知的问题。正如他们所建议的,如果我在属性上使用Ignore(),它会很好地工作。

但是,我在一个具有Type属性的项目中有许多类。是否有任何优雅的方法可以在不在所有单独映射上添加Ignore的情况下为所有这些类处理此问题?


编辑

我目前正在使用AutoMapper 3.3.1.0。正如Yacoub的回答中所说,这个问题似乎在版本4中得到了解决。我需要一些时间来更新软件包,同时一些变通方法会有所帮助。

AutoMapper错误地映射了名为Type的属性-如何处理多个类

正如您在问题中所指出的,这是一个已知的问题,它似乎在以后的版本中得到了解决。我在最新版本(4.0.4(中测试了您的代码,问题已经解决。

因此,您可能需要更新您的AutoMapper版本。

Mapper.CreateMap不是线程安全的。在多个地方使用它不是一个好方法。

在App_start中创建一个静态类文件,并在其中注册所有映射。所以它在应用程序启动时初始化。此外,您不需要在其他地方调用Mapper.CreateMap

public static class AutoMapperConfig
{
    public static void RegisterMappings()
    {
      Mapper.CreateMap<SoldierDTO, Officer>()
      .ForMember(dest => dest.BaseGroup, opt => opt.MapFrom(src => src.Category))
      .ForMember(dest => dest.ActiveFrom, opt => opt.UseValue(DateTime.Now));
      .ForMember(dest => dest.Type, opt => opt.Ignore());
    }
}

在global.asax.cs 中

 protected void Application_Start()
 {
   AutoMapperConfig.RegisterMappings();
 }

您可以在线程安全的应用程序位置使用Mapper.Map方法。

var soldier = new SoldierDTO { Id = 11, Name = "Rackham", Category = "Gunner" };
var officer = Mapper.Map<Officer>(soldier);