注意:我也在AutoMapper 邮件列表上问过这个问题
我的 MVC 应用程序本质上具有两个级别的映射(针对此问题进行了简化):
RepositoryObject <-> Entity <-> ViewModel
我们创建了两个配置文件,每个配置文件处理适当映射级别的配置。
“RepositoryObjects”最终被序列化为 XML 并用于 REST Web 服务。我们发现的问题是 RepositoryObject 中的空集合会序列化为 XML 中的空元素,这会导致问题,因为 Web 服务要么不期望任何元素,要么期望包含数据的元素。
我们能够使用 AllowNullCollections 配置设置解决此问题。这将(当然)创建一个空集合而不是一个空集合,然后可以很好地序列化。
但是,我并不完全愿意将其作为全局设置,因为正如Jimmy 所指出的那样,它并不是真正的最佳实践。我很高兴将它包含在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>();
});
}
}
}
映射测试.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
不为空。