【问题标题】:Map string to enum with Automapper使用 Automapper 将字符串映射到枚举
【发布时间】:2011-04-14 16:58:47
【问题描述】:

我的问题是从数据库返回的 Linq2Sql 对象中为 Viewmodel 补水。我们已经在一些领域做到了这一点,并为它设计了一个很好的分层模式,但最新的项目要求使用一些枚举,这引起了各方的头痛。目前我们从数据库中拉回然后使用 Automapper 水合(或展平)到我们的视图模型中,但是模型中的枚举似乎会导致 Automapper 出现问题。我尝试创建足以满足我所有其他映射要求的自定义解析器,但在这种情况下它不起作用。

代码示例如下:

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 中使用一个字符串,但我不喜欢魔术字符串,并且这个特殊的项目被助手用来在许多地方执行一些逻辑。

【问题讨论】:

  • D'oh 在仔细查看源代码和我的模型中的示例后,我首先意识到了一些事情,由于某种原因,我将 ViewModel 上的 enum 属性设置为可空,这导致了主要问题??!!第二件事是我没有考虑到我们的视图“直接借记”返回的空白应该是 DirectDebit。一旦我删除了这些问题,Automapper 没有自定义解析器等就解决了。呜呼
  • +1 用于提及 ValueInjecter ;)

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


【解决方案1】:

这是 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);
    }
}

【讨论】:

  • 谢谢 Jason.. 我去试试你的解决方案,但我不明白 .Context.SourceValue 和 source.New 是从哪里来的?我是不是错过了什么……对不起,我知道这是一个菜鸟。
  • 嗨 Jason 感谢您的指点,如果您在上面看到我的评论,我已经对其进行了排序,无需自定义解析器。还是谢谢你,给我指点样品是一个很大的帮助
【解决方案2】:

这是一个使用 ValueInjecter 的解决方案: 既然你已经解决了这个问题,我只想给你指出类似的东西:

AutoMapper strings to enum descriptions

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

关于 ValueInjecter 作为替代方案:是的,它为所需的每一件小事提供更通用的无配置,并构建您可以想象的任何约定

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 2019-01-29
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多