首页 > 解决方案 > 如何对可能为空的属性应用 AutoMapper ValueConverters

问题描述

我认为这是一个 AutoMapper 错误,但他们在 GitHub 中的问题模板状态是先向 SO 发布一些内容。

我希望能够应用一个IValueConverter而不用担心空异常。

例如,我使用 aIValueConverter在多个映射中应用一些逻辑:

public class ExampleConverter : IValueConverter<string, string>
{
    public string Convert(string sourceMember, ResolutionContext context)
    {
        if (string.IsNullOrEmpty(sourceMember))
        {
            return string.Empty;
        }

        return sourceMember.ToUpper();
    }
}

如果我有以下类型,我将映射到以下类型:

public class ExampleSource
{
    public ExampleNestedSource1 A { get; set; }
}

public class ExampleNestedSource1
{
    public ExampleNestedSource2 B { get; set; }
}

public class ExampleNestedSource2
{
    public string Input { get; set; }
}

public class ExampleDestination
{
    public string Output { get; set; }
}

我可以像这样应用转换器:

public class ExampleProfile : Profile
{
    public ExampleProfile()
    {
        this.CreateMap<ExampleSource, ExampleDestination>(MemberList.None)
            .ForMember(dst => dst.Output, opt => opt.ConvertUsing(new ExampleConverter(), src => src.A.B.Input));
    }
}

然而,像这样使用转换器,当 A 或 B 为空时会引发异常:

mapper.Map<ExampleDestination>(new ExampleSource // Throws null reference
{
    A = new ExampleNestedSource1(),
});
mapper.Map<ExampleDestination>(new ExampleSource()); // Throws null reference

因为opt.ConvertUsing(new ExampleConverter(), src => src.A.B.Input)接受一个表达式,所以我不能使用像src?.A?.B?.Input.

如果我删除转换器并使用MapFrom,问题就会消失:

public class ExampleProfile : Profile
{
    public ExampleProfile()
    {
        this.CreateMap<ExampleSource, ExampleDestination>(MemberList.None)
            .ForMember(dst => dst.Output, opt => opt.MapFrom(src => src.A.B.Input));
    }
}

MapFrom不支持IValueConverter它只支持IMemberValueResolver可重用性较低的。

有没有更好的方法来处理这种情况?

如果没有,我认为 AutoMapper 应该:

标签: automapperautomapper-10

解决方案


推荐阅读