注意:我也在AutoMapper mailing list
上提出了这个问题我的MVC应用程序基本上有两个映射级别(针对此问题进行了简化):
RepositoryObject <-> Entity <-> ViewModel
我们创建了两个配置文件,每个配置文件都处理相应映射级别的配置。
“RepositoryObjects”最终被序列化为XML并用于REST Web服务。我们发现的问题是RepositoryObject中的空集合将序列化为XML中的空元素,这会导致问题,因为Web服务要么没有元素,要么是包含数据的元素。
我们可以使用AllowNullCollections配置设置解决此问题。这将(当然)创建一个空集合而不是一个空集合,然后序列化很好。
然而,作为一个全球性的设置,我并不完全习惯,因为Jimmy has pointed out,这不是最好的做法。我很高兴在RepositoryObject <-> Entity
映射中使用它,因为RepositoryObjects是自动生成的(无论如何都是丑陋的)并且它在应用程序中非常低级。但如果可能的话,我宁愿不“破坏”Entity <-> ViewModel
映射。
那么,是否可以为每个配置文件配置此设置?
感谢。
更新
我在这里创建了测试代码:https://gist.github.com/4069909
复制此处以供参考:
ProfileClasses.cs
namespace NullCollectionIssue
{
using System.Collections.Generic;
public class SourceProfileOne
{
public ICollection<string> Stuff { get; set; }
}
public class DestProfileOne
{
public ICollection<string> Stuff { get; set; }
}
public class SourceProfileTwo
{
public ICollection<string> Stuff { get; set; }
}
public class DestProfileTwo
{
public ICollection<string> Stuff { get; set; }
}
}
AutoMapperConfigurator.cs
namespace NullCollectionIssue
{
using AutoMapper;
public class ProfileOne : Profile
{
public override string ProfileName
{
get
{
return "ProfileOne";
}
}
protected override void Configure()
{
AllowNullCollections = true;
Mapper.CreateMap<SourceProfileOne, DestProfileOne>();
}
}
public class ProfileTwo : Profile
{
public override string ProfileName
{
get
{
return "ProfileTwo";
}
}
protected override void Configure()
{
Mapper.CreateMap<SourceProfileTwo, DestProfileTwo>();
}
}
public static class AutoMapperConfigurator
{
public static void Configure()
{
Mapper.Initialize(x =>
{
x.AddProfile<ProfileOne>();
x.AddProfile<ProfileTwo>();
});
}
}
}
MappingTests.cs
namespace NullCollectionIssue
{
using AutoMapper;
using NUnit.Framework;
[TestFixture]
public class MappingTests
{
[Test]
public void AutoMapper_Configuration_IsValid()
{
AutoMapperConfigurator.Configure();
Mapper.AssertConfigurationIsValid();
}
[Test]
public void AutoMapper_ProfileOne_AllowsNullCollections()
{
AutoMapperConfigurator.Configure();
Mapper.AssertConfigurationIsValid();
var source = new SourceProfileOne { Stuff = null };
var dest = Mapper.Map<SourceProfileOne, DestProfileOne>(source);
Assert.That(dest, Is.Not.Null);
Assert.That(dest.Stuff, Is.Null);
}
[Test]
public void AutoMapper_ProfileTwo_DoesntAllowNullCollections()
{
AutoMapperConfigurator.Configure();
Mapper.AssertConfigurationIsValid();
var source = new SourceProfileTwo { Stuff = null };
var dest = Mapper.Map<SourceProfileTwo, DestProfileTwo>(source);
Assert.That(dest, Is.Not.Null);
Assert.That(dest.Stuff, Is.Not.Null);
Assert.That(dest.Stuff, Is.Empty);
}
}
}
测试AutoMapper_Configuration_IsValid
和AutoMapper_ProfileTwo_DoesntAllowNullCollections
通过,但测试AutoMapper_ProfileOne_AllowsNullCollections
失败,因为dest.Stuff
不为空。
答案 0 :(得分:1)
查看此功能的source code of the initial commit,看来这是一个配置文件属性 - 请查看Profile.cs。
所以,我想,它应该适用于每个配置文件。我没试过。
答案 1 :(得分:1)
您收到此行为是因为您在configure方法中调用静态Mapper.Map
:
protected override void Configure()
{
Mapper.CreateMap<SourceProfileTwo, DestProfileTwo>();
}
应该是
protected override void Configure()
{
CreateMap<SourceProfileTwo, DestProfileTwo>();//leading Mapper. removed
}