【问题标题】:Auto Mapper Unmapped members were found发现 Auto Mapper 未映射的成员
【发布时间】:2015-02-06 05:26:43
【问题描述】:

我们正在为一个项目使用Automapper,并且似乎随机得到以下错误:

AutoMapper.AutoMapperConfigurationException:找到未映射的成员。查看下面的类型和成员。添加自定义映射表达式、忽略、添加自定义解析器或修改源/目标类型

代码已几个月未更改。我得到那个错误,刷新并且错误消失了,页面工作正常。我正在使用

Mapper.AssertConfigurationIsValid();

不知道为什么它抱怨映射不好,然后刷新,又好了,有人遇到过这个吗?调试无济于事,因为它是随机的,有时没有错误,然后有时它会在网站上的某个地方弹出,再回来就可以了。该错误也会出现在随机页面上,不是同一页面,也不是同一映射。

【问题讨论】:

  • 之后可能“工作正常”,因为对 AssertConfigurationIsValid 的调用发生在应用启动时,应用现在已启动,因此不会再次被调用。
  • 内部异常应该能准确地告诉您问题所在。
  • @KirkWoll 我猜是一样的,这是由于应用程序在一天中第一次启动,也许在它进行映射时有些东西还没有准备好。我尝试重置 IIS 和应用程序池,但它再次随机无法复制错误。
  • @AndrewWhitaker 完整错误是 AutoMapper.AutoMapperConfigurationException:找到未映射的成员。查看下面的类型和成员。添加自定义映射表达式,忽略,添加自定义解析器,或修改源/目标类型 RETel -> SelectItem (Destination member list) DomainClasses.RETel -> Models.SelectItem (Destination member list) 但再次刷新就可以了,并且此映射并不总是在此页面上发生。我已经在其他页面上获得了其他映射,但并不总是发生。
  • 好吧,如果你解决了你看到的问题,那么它们就不会再出现了。您还可以创建一个单元测试,在您的映射上调用 AssertConfigurationIsValid 并获取问题的完整列表

标签: c# asp.net automapper


【解决方案1】:

就我而言,我忘记将地图配置添加到 MapConfig.cs。

【讨论】:

    【解决方案2】:

    快速介绍编辑:正如@mrTurkay 在下面的回答,这可以通过以下配置解决:

    cfg.ValidateInlineMaps = false;
    

    但是,您首先应该了解问题出现的原因 - 请继续阅读。

    当您尝试映射未为其创建映射配置的对象时,会出现此问题。您需要记住的是,它不一定是您要映射的特定对象;但它的导航属性之一。

    假设你有一个Car.cs,你想映射到一个CarDTO.cs

    Car.cs 看起来像这样:

    public class Car
    {
      public string Color { get; set; }
    
      public Engine Engine { get; set; }
    }
    

    您的 DTO 看起来相同,但引用了 EngineDTO

    public class CarDTO
    {
      public string Color { get; set; }
    
      public EngineDTO Engine { get; set; }
    }
    

    您这样配置映射:

        Mapper.CreateMap<DTO.CarDTO, Data.Model.Car>();
        Mapper.CreateMap<Data.Model.Car, DTO.CarDTO>();
    
        Mapper.CreateMap<DTO.EngineDTO, Data.Model.Engine>();
        Mapper.CreateMap<Data.Model.Engine, DTO.EngineDTO>();
    

    一切看起来都很好,对吧?但是,在您的 EngineDTO 中,您可能有一个导航属性,例如:

    public class EngineDTO
    {
    public List<PartDTO> Parts { get; set; }
    }
    

    因此,当 Automapper 从 Engine 映射到 EngineDTO 时,它也会尝试映射 PartDTO,但由于您忘记在 global.asax 中声明映射,您会收到错误消息:

    AutoMapper.AutoMapperConfigurationException:未映射的成员是 成立。查看下面的类型和成员。添加自定义映射 表达式,忽略,添加自定义解析器,或修改 源/目标类型

    如果您不想在类上映射某些属性,可以使用 Ignore:

    Mapper.CreateMap<Engine, EngineDTO>()
        .ForMember(x => x.Parts, opt => opt.Ignore());
    

    编辑:

    对于更健壮的 AutoMapper 配置,我建议您使用映射配置文件,而不是直接在 Global.asax 中声明映射。这是一个例子:

    简介:

    public class CarProfile : Profile
    {
        public CarProfile ()
        {
            CreateMap<Car, CarDTO>();
        }
    }
    

    全球.asax:

    Mapper.Initialize(cfg =>
    {
         cfg.AddProfile<CarProfile>();
    }
    

    【讨论】:

    • 有什么方法可以忽略未映射的属性?
    • @tchelidze 是的,你可以忽略属性:“.ForMember(dest => dest.Users, options => options.Ignore()”
    • @SimonD 谢谢西蒙,我的意思是隐式而不是明确地忽略成员
    【解决方案3】:

    这是关于验证。

    cfg.ValidateInlineMaps = false;
    

    应该够了

    【讨论】:

    • 这个答案被严重低估了。我一直在努力将旧的 AutoMapper 2.x 配置转换为 8.x,而无需手动更改数百个映射语句。几乎我所有的地图都是旧格式的简单 Mapper.CreateMap() 。似乎删除所有这些并使用 AutoMapper.Mapper.Initialize(cfg => { cfg.ValidateInlineMaps = false; cfg.CreateMissingTypeMaps = true; });到目前为止,在应用程序启动中是一个足够的替代品,除了一些边缘情况。
    • 这些建议似乎都不再有效,因为 MapperConfiguration 没有公开名为 ValidateInlineMaps 的成员,而 Mapper 也没有公开名为 Initialize 的成员。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 2016-03-23
    相关资源
    最近更新 更多