0

I'm using AutoMapper 6.1.1.0 and have the following types:

Source:

public class PaymentPlan
{
    private List<ScheduledPayment> _scheduledPayments = new List<ScheduledPayment>();
    private Rates _ratesApplied;

    public Rates RatesApplied
    {
        get { return _ratesApplied; }
        set { _ratesApplied = value; }
    }

    public List<ScheduledPayment> ScheduledPayments
    {
        get { return _scheduledPayments; }
        set { _scheduledPayments = value; }
    }
}

Dest:

public class PaymentPlanModel
{
    public RatesModel RatesApplied { get; set; }

    public List<ScheduledPaymentModel> ScheduledPayments { get; set; }
}

public class ClassEnrollmentPaymentPlanVM : PaymentPlanModel
{
    public Guid PricePlanID { get; set; }

    public string Name { get; set; }

    public bool IsSelected { get; set; }

    public bool AutoDraftEnabled { get; set; }

    public bool BillingDayChoiceEnabled { get; set; }

    public List<int> AvailableBillingDays { get; set; }

    public int SelectedBillingDay { get; set; }
}

Mapping config profile:

CreateMap<Rates, RatesModel>();
CreateMap<ScheduledPayment, ScheduledPaymentModel>();
CreateMap<PaymentPlan, PaymentPlanModel>();
CreateMap<PaymentPlan, ClassEnrollmentPaymentPlanVM>();
    //.IncludeBase<PaymentPlan, PaymentPlanModel>();

ClassEnrollmentPaymentPlanVM inherits PaymentPlanModel. I'm trying to map from a source PaymentPlan into a ClassEnrollmentPaymentPlanVM to populate all the base PaymentPlanModel properties, but it's complaining that it is "Missing type map configuration or unsupported mapping." for Rates -> RatesModel. In troubleshooting this error I tried commenting out my IncludeBase call but get the same result. I have quadruple checked the namespaces are correct. Why isn't it finding my mapping from Rates to RatesModel?

Edit:

The mapping is initiated like this:

private static IMapper _mapper = MapperConfig.EntityWebMapper;
...

PaymentPlan paymentPlan = pmtCalc.CalculatePaymentPlan(calcInput);

ClassEnrollmentPaymentPlanVM paymentPlanVM = _mapper.Map<ClassEnrollmentPaymentPlanVM>(paymentPlan);

And the exact exception/error message is an AutoMapperMappingException stating:

Error mapping types.

Mapping types: PaymentPlan -> ClassEnrollmentPaymentPlanVM CRM.Logic.CRM.PaymentCalculation.PaymentPlan -> CRM.MVCWeb.ViewModels.Enrollment.ClassEnrollmentPaymentPlanVM

Type Map configuration: PaymentPlan -> ClassEnrollmentPaymentPlanVM CRM.Logic.CRM.PaymentCalculation.PaymentPlan -> CRM.MVCWeb.ViewModels.Enrollment.ClassEnrollmentPaymentPlanVM

Property: RatesApplied

Inner Exception Message:

Missing type map configuration or unsupported mapping.

Mapping types: Rates -> RatesModel CRM.Logic.CRM.PaymentCalculation.Rates -> CRM.MVCWeb.Models.PaymentCalculation.RatesModel

xr280xr
  • 12,621
  • 7
  • 81
  • 125
  • Please edit your question to include a [mcve] which can be compiled and tested by others. Also, why do you have two `CreateMap()` mappings from the same source type? What is the full error message you get? Can you call `AssertConfigurationIsValid()` to get additional/further information about your mapping? – Progman Dec 19 '18 at 16:10
  • I'll take that to mean it looks like it should be working to you too. I created an example project using the code I posted and am not able to reproduce it so far >:(, still working on it. I have two mappings from the same source type because I want to be able to map from the source type to either a `PaymentPlanModel`, or, as in this case, a `ClassEnrollmentPaymentPlanVM` view model. `PaymentPlanModel` is for general use of a payment plan in code where `ClassEnrollmentPaymentPlanVM` is a view-specific version of that that simply adds some additional properties for the view. Stand by... – xr280xr Dec 19 '18 at 16:52
  • 1
    Based on what you've posted, there's not a lot of ways it could fail. Here are a couple of things to check. Does RatesModel have a parameterless constructor? Does Rates or RatesModel have a property whose type does not have a mapping? – Matthew Brubaker Dec 19 '18 at 17:17
  • I added the error information. @Matthew They have implicit parameterless constructors - no constructors (or methods) are declared. All of their properties are primitives - 6 `decimal`s and an `int`. `Rates` has internal private members exposed by its properties. `RatesModel` has auto-implemented properties. But notice the inner exception is missing a type map for `Rates` to `RatesModel` in the inner exception. Am I correct in thinking that is occurring before it even looks at those types' contained properties? It matches the properties on name & thinks it doesn't have a mapping of their types? – xr280xr Dec 19 '18 at 18:38
  • That looks like the `IMapper` instance you're getting from `MapperConfig.EntityWebMapper` isn't using the mapping configuration you set up with the various `CreateMap<>` calls. If that's not the case, you might try setting the member mappings explicitly. eg `CreateMap().ForMember(d=>d.RatesApplied,opt=>opt.MapFrom(s=>s.RatesApplied))` – Matthew Brubaker Dec 19 '18 at 19:27
  • @MatthewBrubaker Crap. A faulty source control merge appears to have removed the profile containing the mappings from the configuration... A couple wrong assumptions completely threw me off from looking at the obvious on this one. Thanks for helping me narrow it down. (-‸ლ) – xr280xr Dec 19 '18 at 19:42
  • 1
    Not a problem, glad I could help. Don't feel too bad about it. I'd be lying if I said that (or worse...) had never happened to me. That said, I would recommend you make use of explicit property mappings. They will save you some headaches in the long run due to additional compile time type safety. – Matthew Brubaker Dec 19 '18 at 19:45

0 Answers0