.net 如果属性是接口类型,为什么AutoMapper会尝试映射null属性?
在AutoMapper 5.0.2下: 当源对象具有接口类型的属性时,即使该属性为null,也将完全计算为该接口类型定义的映射。如果映射使用ResolveUsing,则会出现问题,因为它可能不需要null,并且可能会抛出 下面的测试夹具使用一个相当人为的映射来突出问题。一个测试通过,另一个测试失败:.net 如果属性是接口类型,为什么AutoMapper会尝试映射null属性?,.net,automapper,.net,Automapper,在AutoMapper 5.0.2下: 当源对象具有接口类型的属性时,即使该属性为null,也将完全计算为该接口类型定义的映射。如果映射使用ResolveUsing,则会出现问题,因为它可能不需要null,并且可能会抛出 下面的测试夹具使用一个相当人为的映射来突出问题。一个测试通过,另一个测试失败: [TestFixture] public class NullPropertyTests { public class ChildClass : IChildInterface {
[TestFixture]
public class NullPropertyTests
{
public class ChildClass : IChildInterface
{
public string OtherValue { get; set; }
public string Value { get; set; }
}
public interface IChildInterface
{
string Value { get; set; }
}
public class ClassReferencesChildClass
{
public ChildClass Child { get; set; }
}
public class ClassReferencesChildInterface
{
public IChildInterface Child { get; set; }
}
public class DtoClass
{
public DtoChildClass Child { get; set; }
}
public class DtoChildClass
{
public string OtherValue { get; set; }
public string Value { get; set; }
}
[Test]
public void BreakingTest()
{
var mapper = CreateAndValidateMapper(e =>
{
e.CreateMap<ClassReferencesChildInterface, DtoClass>();
e.CreateMap<IChildInterface, DtoChildClass>()
.Include<ChildClass, DtoChildClass>()
.ForMember(d => d.Value, x => x.ResolveUsing(c => DoStuff(c.Value?.Split(' '))))
.ForMember(d => d.OtherValue, x => x.Ignore());
e.CreateMap<ChildClass, DtoChildClass>();
});
// This fails due to a NullReferenceException:
mapper.Map<DtoClass>(new ClassReferencesChildInterface { Child = null });
}
[Test]
public void PassingTest()
{
var mapper = CreateAndValidateMapper(e =>
{
e.CreateMap<ClassReferencesChildClass, DtoClass>();
e.CreateMap<IChildInterface, DtoChildClass>()
.Include<ChildClass, DtoChildClass>()
.ForMember(d => d.Value, x => x.ResolveUsing(c => DoStuff(c.Value?.Split(' '))))
.ForMember(d => d.OtherValue, x => x.Ignore());
e.CreateMap<ChildClass, DtoChildClass>();
});
mapper.Map<DtoClass>(new ClassReferencesChildClass { Child = null });
}
private static string DoStuff(string[] value)
{
return value.FirstOrDefault();
}
private static IMapper CreateAndValidateMapper(Action<IMapperConfigurationExpression> configure)
{
var configuration = new MapperConfiguration(configure);
configuration.AssertConfigurationIsValid();
return configuration.CreateMapper();
}
}
[TestFixture]
公共类NullPropertyTests
{
公共类子类:IchilInterface
{
公共字符串OtherValue{get;set;}
公共字符串值{get;set;}
}
公共接口IchilInterface
{
字符串值{get;set;}
}
公共类ClassReferencesChildClass
{
公共子类子{get;set;}
}
公共类ClassReferencesChildInterface
{
公共i接口子项{get;set;}
}
公共类DTO类
{
公共DtoChildClass子级{get;set;}
}
公共类DtoChildClass
{
公共字符串OtherValue{get;set;}
公共字符串值{get;set;}
}
[测试]
公共破空测试()
{
变量映射器=CreateAndValidateMapper(e=>
{
e、 CreateMap();
e、 CreateMap()
.包括()
.ForMember(d=>d.Value,x=>x.ResolveUsing(c=>DoStuff(c.Value?.Split(“”)))
.ForMember(d=>d.OtherValue,x=>x.Ignore());
e、 CreateMap();
});
//由于NullReferenceException,此操作失败:
Map(新的ClassReferencesChildInterface{Child=null});
}
[测试]
public void PassingTest()
{
变量映射器=CreateAndValidateMapper(e=>
{
e、 CreateMap();
e、 CreateMap()
.包括()
.ForMember(d=>d.Value,x=>x.ResolveUsing(c=>DoStuff(c.Value?.Split(“”)))
.ForMember(d=>d.OtherValue,x=>x.Ignore());
e、 CreateMap();
});
Map(新的ClassReferencesChildClass{Child=null});
}
私有静态字符串DoStuff(字符串[]值)
{
返回值.FirstOrDefault();
}
专用静态IMapper CreateAndValidateMapper(操作配置)
{
var配置=新的MapperConfiguration(配置);
assertConfigurationsValid();
返回configuration.CreateMapper();
}
}
根据AutoMapper 3.2.1(根据编译需要调整类型等),两个测试都将通过
我们可以修改几十个映射来显式地容忍空值,但对于以前工作正常的东西来说,这似乎过于冗长了
这是故意的行为吗?是否有一种不需要复制大量映射的解决方法?我提出了这个问题。它似乎已被修复,修复程序将在5.1.0中发布