How can I use automapper to map 2 enums that use different casing

我与影子孤独终老i 提交于 2021-01-28 20:33:18

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!