2010-09-20 11 views
8

Il mio problema è idratare un Viewmodel da un oggetto Linq2Sql che è stato restituito dal database. Lo abbiamo fatto in alcune aree e abbiamo elaborato un bel modello a strati, ma l'ultimo elemento richiede l'uso di alcune enumerazioni e questo ha causato mal di testa a tutto tondo. Attualmente ritiriamo dal database, quindi usiamo Automapper per idratare (o appiattire) nei nostri Viewmodels ma avere le enumerazioni nel modello sembra causare problemi con Automapper. Ho provato a creare resovlers personalizzati che sono sufficienti per tutti i miei altri requisiti di mapping ma non funziona in questa istanza.Stringa di mappa per enum con Automapper

Un esempio del codice si presenta come:

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>()) 

ottengo il seguente errore

[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 

mi piacerebbe restare con Automapper per tutte le nostre azioni di mappatura, ma ho visto un sacco di gente dice che non fa questo tipo di mappature quindi sto cominciando a chiedermi se lo sto usando nel modo sbagliato? Inoltre, ho visto alcune menzioni di ValueInjecter - questa è un'alternativa ad Automapper, o sarà utile semplicemente tappare i buchi di Automapper per l'idratazione dei modelli e usare Automapper per l'appiattimento?

Sì, potrei semplicemente usare una stringa nel mio ViewModel, ma non sono un fan delle stringhe magiche, e questo particolare elemento viene utilizzato dagli helper per eseguire alcune logiche in un numero di punti.

+0

D'oh dopo aver guardato più da vicino gli esempi nella fonte ei miei modelli I ho realizzato un paio di cose in primo luogo, per qualche motivo ho reso la proprietà enum sul nullable di ViewModel che ha causato i problemi principali ?? !! La seconda cosa era che non avevo considerato lo spazio bianco restituito dal nostro punto di vista "Direct Debit" avrebbe dovuto essere DirectDebit .. Una volta rimossi questi problemi, Automapper lo ha fatto senza i risolutori personalizzati ecc. Woo hoo –

+0

+1 per menzionare ValueInjecter;) – Omu

risposta

9

Questo è un problema con la documentazione di AutoMapper. Se scarichi la fonte AutoMapper, ci sono degli esempi. Il codice che si desidera sarà simile a questa:

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); 
    } 
} 
+0

Grazie Jason .. Sono andato a provare la soluzione ma non riesco a capire da dove provengono .Context.SourceValue e la sorgente. Mi sto perdendo qualcosa ... scusa un po 'di noob, lo so. –

+0

Ciao Jason Grazie per i suggerimenti se vedi il mio commento sopra ho ottenuto risolto con la necessità di risolutori personalizzati. Grazie ugualmente e indicandomi i campioni è stato di grande aiuto –

+0

Sicuramente nessun problema! –

5

ecco una soluzione con il ValueInjecter: dal momento che già risolto il problema che sto solo andando a puntare a qualcosa di simile:

AutoMapper strings to enum descriptions

in questa domanda i requisiti erano un po 'più di fare da stringa a enum, ma include anche questa conversione

sul ValueInjecter è un'alternativa: sì, fa più generica nessuna configurazione per ogni piccola cosa richiesta, e costruisci qualsiasi convenzione tu possa immaginare

+0

Cheers, per quello lo guarderò bene. –