rboarman
rboarman

Reputation: 8214

AutoMapper resolver not passing expected type

Given the following classes and resolver, why am I getting this error? I don't see why ProductAddModel is being passed in at all.

AutoMapper.AutoMapperMappingException was unhandled by user code
Message=Value supplied is of type System.Decimal but expected AuctionCMS.Framework.Models.Admin.ProductAddModel. Change the value resolver source type, or redirect the source value supplied to the value resolver using FromMember.

Types:

    public class Currency
    {
        public Int64 Value { get; set; }
        // Spot saved for currency type and any other extra properties
    }

   public class Product
    {
        public Currency Price { get; set; }
        public Currency ReservePrice { get; set; }
          }

    public class ProductAddModel
    {
        public Decimal Price { get; set; }
        public Decimal ReservePrice { get; set; }
    }

Resolver code:

public class DecimalToCurrencyValueResolver : ValueResolver<decimal, Currency>
{
    #region Overrides of ValueResolver<decimal,Currency>

    protected override Currency ResolveCore(decimal source)
    {
        return new Currency() { Value = (Int64)((decimal)source) * 1000 };
    }

    #endregion
}

public class CurrencyToDecimalValueResolver : ValueResolver<Currency, decimal>
{
    #region Overrides of ValueResolver<decimal,Currency>

    protected override decimal ResolveCore(Currency source)
    {
        return (decimal)source.Value * 1000;
    }

Mapping code:

            Mapper.CreateMap<ProductAddModel, Product>()
                .ForMember(x => x.Price, opt => opt.ResolveUsing<DecimalToCurrencyValueResolver>())
                .ForMember(x => x.ReservePrice, opt => opt.ResolveUsing<DecimalToCurrencyValueResolver>());
            Mapper.CreateMap<Product, ProductAddModel>()
                .ForMember(x => x.Price, opt => opt.ResolveUsing<CurrencyToDecimalValueResolver>())
                .ForMember(x => x.ReservePrice, opt => opt.ResolveUsing<CurrencyToDecimalValueResolver>());

var model = new ProductAddModel();
var product = new Product();
Mapper.Map<ProductAddModel, Product>(model, product);

What am I doing wrong and is this approach the best way to handle simple transforms during the mapping process?

Thanks!

Upvotes: 4

Views: 1384

Answers (2)

user3626204
user3626204

Reputation: 1

In resolver decimal is used and in mapping productAddModel is passed. So mapping should be like this

Mapper.CreateMap<ProductAddModel, Product>()
                .ForMember(x => x.Price, opt => opt.ResolveUsing<DecimalToCurrencyValueResolver>().FromMember(e => e.Value ));

Upvotes: 0

k0stya
k0stya

Reputation: 4315

Use TypeConverters instead:

    public  class CurrencyToDecimalTypeConverter : ITypeConverter<Currency, Decimal>
    {
        public decimal Convert(ResolutionContext context)
        {
            return ((Currency)context.SourceValue).Value * 1000;
        }
    }

    public class DecimalToCurrencyTypeConverter : ITypeConverter<Decimal, Currency>
    {
        public Currency Convert(ResolutionContext context)
        {
            return new Currency() { Value = (Int64)((decimal)context.SourceValue) * 1000 };
        }
    }

Here is configuration:

Mapper.CreateMap<ProductAddModel, Product>();
Mapper.CreateMap<Product, ProductAddModel>();
Mapper.CreateMap<Decimal, Currency>().ConvertUsing<DecimalToCurrencyTypeConverter>();
Mapper.CreateMap<Currency, Decimal>().ConvertUsing<CurrencyToDecimalTypeConverter>();

var model = new ProductAddModel();
var product = new Product();
Mapper.Map<ProductAddModel, Product>(model, product);

Upvotes: 3

Related Questions