Automapper:忽略目标属性的验证异常

Posted

技术标签:

【中文标题】Automapper:忽略目标属性的验证异常【英文标题】:Automapper: validation exception ignoring destination property 【发布时间】:2021-12-23 17:47:18 【问题描述】:

我在尝试忽略目标属性时遇到了麻烦

源类:

public class ClassDto

    public int Id  get; set; 

目的地类:

public class ClassModel


    public int Id  get; set; 

    public IList<string> ListString  get; set; 


例子:

public class Program

    static void Main(string[] args)
    
        var dto = new ClassDto  Id = 1 ;

        var config = new MapperConfiguration(cfg =>
        
            cfg.CreateMap<ClassDto, ClassModel>().
            ForMember(i => i.ListString, opt => opt.DoNotUseDestinationValue()); 
        );

        config.AssertConfigurationIsValid();

        var mapper = config.CreateMapper();

        var model = mapper.Map<ClassDto, ClassModel>(dto);

    

不幸的是 config.AssertConfigurationIsValid();引发异常:

$exception "\n找到未映射的成员。查看下面的类型和成员。\n添加自定义映射表达式,忽略,添加自定义 解析器,或修改源/目标类型\n如果没有匹配 构造函数,添加无参数 ctor,添加可选参数,或映射所有 构造函数 参数\n================================================= ====\r\nClassDto -> ClassModel(目标成员列表)\r\nAutoMapperFoo.ClassDto -> AutoMapperFoo.ClassModel(目标成员列表)\r\n\r\n未映射 属性:\r\nListString\r\n" AutoMapper.AutoMapperConfigurationException

我无法理解为什么,我明确地通过 DoNotUseDestinationValue 忽略 ListString

提前致谢

【问题讨论】:

UseDestinationValue() 并不意味着忽略映射成员。这意味着不要使用新对象对其进行初始化(如果已映射,则映射到现有值)。 AutoMapper 仍会尝试映射该成员。如果没有匹配的源成员映射,验证将抛出异常,因为UseDestinationValue() 表示无论映射是否存在都保留成员的现有值。令人困惑的命名选择,但这就是它的工作原理。 【参考方案1】:

默认情况下,AutoMapper 会尝试映射源中的所有属性 当源类型和目标类型都为目标类型时 属性名称相同。如果您希望某些属性不映射 使用目标类型属性,那么您需要使用 AutoMapper 忽略 C# 中的属性。了解更多AutoMapper Ignore Property in C#

Automapper 提供属性 Ignore 告诉映射器不要 从源类中获取属性的值。 忽略不仅 忽略属性的映射,同时也忽略 的映射 所有内在属性。这意味着如果属性不是原始的 类型,但是另一个类,如果你使用 Ignore,这个类 属性不会被映射。所以,A.B.C 将是 A.Null。

所以尝试使用这个:

.ForMember(x => x.ListString, opt => opt.Ignore())

【讨论】:

据我所知,Ignore 已经过时,我们必须使用 DoNotUseDestinationValue 好吧,我的错,我不知道这个,你有任何关于这个的有效消息来源吗? 好吧,我犯了一个错误。我无法访问我阅读的文档并且您的解决方案有效。所以谢谢,没关系 没问题!乐于助人^_^ Ignore() 将绕过目标成员的映射。 UseDestinationValue() 不会用新构造的对象替换目标成员,但仍会尝试映射它。但是,UseDestinationValue() 有一个微妙的错误,它会抛出一个验证异常,即该成员仍然未映射,即使它是。如果您知道不存在源成员,请使用Ignore()

以上是关于Automapper:忽略目标属性的验证异常的主要内容,如果未能解决你的问题,请参考以下文章

从源映射到现有目标时,AutoMapper 不会忽略 List

Automapper 忽略 null 值,但将空字符串映射到 null

如何在 automapper 中为 aftermap 上的目标属性赋值

AutoMapper的介绍与使用

如何使用 AutoMapper 将父引用分配给子属性

AutoMapper 根据其他模型属性值映射所有属性