如何配置AutoMapper全局选项实现源值为空时目标值设为null
问题解决:AutoMapper源属性为Null时设置目标属性为Null
问题原因
在AutoMapper的更新模式(即调用Map(source, existingDestination)更新已有对象)下,默认行为是忽略源中的Null引用属性,不会覆盖目标的非Null值。当存在PersonPatchTest -> PersonTest的映射时,AutoMapper会将CEO识别为可映射的复杂类型,因此即使源CEO为Null,也不会主动将目标CEO设为Null,除非明确配置覆盖这一默认行为。
AllowNullDestinationValues配置仅控制是否允许目标属性被设置为Null,但不会改变更新模式下忽略Null源值的默认规则,因此单独设置它无法解决问题。
解决方案
方案1:针对单个成员配置
修改ProfileTest中CompanyPatchTest -> CompanyTest的映射,为CEO成员指定NullHandling.Replace,强制源为Null时替换目标值:
public class ProfileTest : Profile { public ProfileTest() { CreateMap<CompanyTest, CompanyPatchTest>(); CreateMap<PersonTest, PersonPatchTest>(); CreateMap<CompanyPatchTest, CompanyTest>(MemberList.Source) .ForMember(d => d.CEO, op => { op.AllowNull(); op.NullHandling(NullHandling.Replace); // 关键配置:源为Null时覆盖目标值 }); CreateMap<PersonPatchTest, PersonTest>(MemberList.Source); } }
方案2:全局配置(所有映射生效)
如果希望所有映射都遵循“源为Null时覆盖目标值”的规则,可在Profile中添加全局配置:
public class ProfileTest : Profile { public ProfileTest() { // 全局设置:所有成员的Null处理规则为Replace ForAllMaps((map, config) => { config.ForAllMembers(op => op.NullHandling(NullHandling.Replace)); }); CreateMap<CompanyTest, CompanyPatchTest>(); CreateMap<PersonTest, PersonPatchTest>(); CreateMap<CompanyPatchTest, CompanyTest>(MemberList.Source); CreateMap<PersonPatchTest, PersonTest>(MemberList.Source); } }
替代工具(若AutoMapper不满足需求)
如果需要更灵活的映射规则,可考虑使用Mapster:
- Mapster默认在更新模式下会处理Null源覆盖目标的场景
- 配置更简洁,支持全局规则和单个成员的精细控制
内容的提问来源于stack exchange,提问作者cap29
相关产品推荐
相关产品推荐

