使用Automapper将字符串映射到枚举

时间:2010-09-20 13:56:52

标签: asp.net-mvc enums viewmodel automapper valueinjecter

我的问题是从已从数据库返回的Linq2Sql对象中保护Viewmodel。我们已经在一些领域做到了这一点并且有一个很好的分层模式,但最新的项目要求使用一些枚举,这引起了全面的麻烦。目前我们从数据库撤回然后使用Automapper将水合(或变平)到我们的View模型中,但是模型中的枚举似乎导致了Automapper的问题。我已经尝试创建自定义resovler,它已满足我所有其他映射要求,但在这种情况下它不起作用。

代码示例如下:

public class CustomerBillingTabView{
    public string PaymentMethod {get; set;}
    ...other details
}

public class BillingViewModel{
    public PaymentMethodType PaymentMethod {get; set;}
    ...other details
}

public enum PaymentMethodType {
    Invoice, DirectDebit, CreditCard, Other
}

public class PaymentMethodTypeResolver : ValueResolver<CustomerBillingTabView, PaymentMethodType>
{
    protected override PaymentMethodType ResolveCore(CustomerBillingTabView source)
    {

        if (string.IsNullOrWhiteSpace(source.PaymentMethod))
        {
            source.PaymentMethod = source.PaymentMethod.Replace(" ", "");
            return (PaymentMethodType)Enum.Parse(typeof(PaymentMethodType), source.PaymentMethod, true);
        }

        return PaymentMethodType.Other;
    }
}

        CreateMap<CustomerBillingTabView, CustomerBillingViewModel>()
        .ForMember(c => c.CollectionMethod, opt => opt.ResolveUsing<PaymentMethodTypeResolver>())

我收到以下错误

[ArgumentException: Type provided must be an Enum.
Parameter name: enumType]
   System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult) +9626766
   System.Enum.Parse(Type enumType, String value, Boolean ignoreCase) +80
   AutoMapper.Mappers.EnumMapper.Map(ResolutionContext context, IMappingEngineRunner mapper) +231
   AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) +720

我想坚持使用Automapper进行所有的映射操作,但是我看到很多人说它没有做这种类型的映射,所以我开始怀疑我是否正在使用它以错误的方式?此外,我已经看到了一些ValueInjecter的提及 - 这是Automapper的替代方案,还是只是插入Automapper中的漏洞来模拟水化并使用Automapper进行展平?

是的我可以在我的ViewModel中使用一个字符串,但我不是魔术字符串的粉丝,帮助者使用这个特殊项目在很多地方执行某些逻辑。

2 个答案:

答案 0 :(得分:10)

这是AutoMapper文档的问题。如果您下载AutoMapper源,那里有一些示例。您想要的代码如下所示:

public class PaymentMethodTypeResolver : ValueResolver<CustomerBillingTabView, PaymentMethodType>
{
    protected override PaymentMethodType ResolveCore(CustomerBillingTabView source)
    {

        string paymentMethod = source.Context.SourceValue as string;

        if (string.IsNullOrWhiteSpace(paymentMethod))
        {
            paymentMethod  = paymentMethod.Replace(" ", "");
            return source.New((PaymentMethodType)Enum.Parse(typeof(PaymentMethodType), paymentMethod, true));
        }

        return source.New(PaymentMethodType.Other);
    }
}

答案 1 :(得分:5)

这是 ValueInjecter 的解决方案: 因为你已经解决了这个问题,我只想指出类似的东西:

AutoMapper strings to enum descriptions

在这个问题中,要求不仅仅是从字符串到枚举,但它还包括这种转换

关于ValueInjecter是另一种选择:是的,它为所需的每件小事做了更通用的配置,并构建你能想象到的任何约定