问题
I have many enums that I want to keep all caps that I have to map to another system that has no standard at all (caps, no caps, pascal, camel). I can't find an automapper flag to tell it to ignore case for enums. I could use a custome converter for each enum but I would prefer a generic converter since there are so many.
Some answers here have implied that automapper does this already. I don't get that from my testing.
If I have these enums:
public enum AllCaps
{
VALUE1,
VALUE2,
VALUE3
}
public enum NoCaps
{
value1,
value2,
value3
}
public enum MixedCaps
{
Value1,
Value2,
Value3
}
These maps:
CreateMap<AllCaps, NoCaps>();
CreateMap<AllCaps, MixedCaps>();
CreateMap<NoCaps, AllCaps>();
CreateMap<NoCaps, MixedCaps>();
CreateMap<MixedCaps, AllCaps>();
CreateMap<MixedCaps, NoCaps>();
This code:
var vAllCaps = new AllCaps();
var vNoCaps = new NoCaps();
var vMixedCaps = new MixedCaps();
vAllCaps = AllCaps.VALUE2;
vNoCaps = NoCaps.value2;
vMixedCaps = MixedCaps.Value2;
var AllCapsToNoCaps = Mapper.Map<AllCaps, NoCaps>(vAllCaps);
var AllCapsToMixedCaps = Mapper.Map<AllCaps, MixedCaps>(vAllCaps);
var NoCapsToAllCaps = Mapper.Map<NoCaps, AllCaps>(vNoCaps);
var NoCapsToMixedCaps = Mapper.Map<NoCaps, MixedCaps>(vNoCaps);
var MixedCapsToAllCaps = Mapper.Map<MixedCaps, AllCaps>(vMixedCaps);
var MixedCapsToNoCaps = Mapper.Map<MixedCaps, NoCaps>(vMixedCaps);
The result of all my mapped variables are either VALUE1, value1, or Value1 and not the expected VALUE2, value2, or Value2.
回答1:
Automapper does a case insensitive mapping between enumerations automatically.
No CreateMap<EnumSource, EnumDest>()
call for an enum is required.
There are some details worth mentioning:
- Enum values embedded inside a mapped type are case insensitive mapped
configuration.AssertConfigurationIsValid()
Does not check if a target value is available for all source values- If a source value does not exist in the target enumeration, the numeric value is taken
The AutoMapper.Extensions.EnumMapping can validate the enumeration mappings, but this extension does a case sensitive check. And it is not really required for a simple enum to enum mapping.
A custom validation can be added to check valid enum mappings
Example Code:
config.Advanced.Validator(context =>
{
if (context.TypeMap != null)
{
foreach (var memberMap in context.TypeMap.MemberMaps)
{
if (memberMap.SourceType.IsEnum && memberMap.DestinationType.IsEnum)
{
var hasMappingError = false;
var sourceEnumValue = Enum.GetValues(memberMap.SourceType).Cast<object>()
.Select(x => x.ToString().ToLowerInvariant()).ToList();
var targetEnumValues = Enum.GetValues(memberMap.DestinationType).Cast<object>()
.Select(x => x.ToString().ToLowerInvariant()).ToList();
var messageBuilder =
new StringBuilder(
$"Missing enum mapping from {memberMap.SourceType.FullName} to {memberMap.DestinationType.FullName}");
messageBuilder.AppendLine();
messageBuilder.AppendLine("The following source values are not mapped:");
foreach (var sourceValue in sourceEnumValue)
{
if (!targetEnumValues.Contains(sourceValue))
{
hasMappingError = true;
messageBuilder.AppendLine($" - {sourceValue}");
}
}
if (hasMappingError)
{
throw new AutoMapperConfigurationException(messageBuilder.ToString());
}
}
}
}
});
来源:https://stackoverflow.com/questions/54534659/how-can-i-use-automapper-to-map-2-enums-that-use-different-casing