注:AutoMapperメーリングリストでもこの質問をしました
私のMVCアプリケーションには、基本的に2つのレベルのマッピングがあります(この質問のために簡略化されています)。
RepositoryObject <-> Entity <-> ViewModel
2つのプロファイルを作成し、それぞれが適切なマッピングレベルの構成を処理します。
「RepositoryObjects」は最終的にXMLにシリアル化され、RESTWebサービスで使用されます。私たちが見つけた問題は、RepositoryObjectの空のコレクションがXMLの空の要素にシリアル化されることでした。これにより、Webサービスが要素を予期していないか、データを含む要素を予期しているため、問題が発生します。
AllowNullCollections構成設定を使用してこれを解決することができました。これにより、(もちろん)空のコレクションではなくnullコレクションが作成され、正常にシリアル化されます。
ただし、ジミーが指摘しているように、これは実際にはベストプラクティスではないため、これをグローバルな設定として使用することは完全には快適ではありません。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
て合格しますが、がnullでないAutoMapper_ProfileOne_AllowsNullCollections
ため、テストは失敗します。dest.Stuff