5

I am using version 9. I am using a Profile based configuration. When I run the application the Mapper.Map<>() method throws the following exception:

JobAssist.Services.ResumeBankMgmt.API.Application.ViewModels.ResumeBankViewModel needs to have a constructor with 0 args or only optional args. (Parameter 'type')

I don't know what is causing this.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Mike Lenart
  • 767
  • 1
  • 5
  • 19
  • Many things require a type to have a *default constructor*. For example. If you have a `new()` constraint on a generic type, that type must have a default constructor. That way, instances of your type can be created using `new` without any knowledge of what parameters are needed for the constructor expression.The fix is to create a default constructor for your type. Classes get default constructor automatically unless you define a non-default one. In that case it's up to you to decide if your type needs one – Flydog57 Mar 23 '20 at 00:39
  • If this is because of DI Constructor injection, automapper has options for this – TheGeneral Mar 23 '20 at 01:44
  • I have other classes that don't require it. Do you know when it is required or what drives to need it? – Mike Lenart Mar 23 '20 at 22:59
  • Can you post your code for your configuration inside Profile? – Lee Song Oct 08 '20 at 12:06
  • @LeeSong I got it solved. Why do you need it? – Mike Lenart Nov 01 '20 at 21:56

4 Answers4

10

The issue was that I had one parameter that was not named exactly like my class property. See I changed categories in constructor to resumeCategories.

Original code:

public class ResumeBankViewModel
{
    public List<ResumeCategoryViewModel> ResumeCategories { get; set; }
    
    public ResumeBankViewModel(int id, int jobSeekerID, List<ResumeViewModel> resumes, List<ResumeCategoryViewModel> categories)
}

new code:

public class ResumeBankViewModel
{
    public List<ResumeCategoryViewModel> ResumeCategories { get; set; }

    public ResumeBankViewModel(int id, int jobSeekerID, List<ResumeViewModel> resumes, List<ResumeCategoryViewModel> resumeCategories)
}
An Nguyen
  • 96
  • 1
  • 2
  • 6
Mike Lenart
  • 767
  • 1
  • 5
  • 19
2

Assuming you have access to the source code, and this isn't in a 3rd party assembly you're referencing...

Find the definition of the class ResumeBankViewModel (ViewModels\ResumeBankViewModel.cs is probably a good place to start.)

And add this line:

public ResumeBankViewModel(){ }

If there is a line like this:

private ResumeBankViewModel() /* { etc. } */

Or this:

internal ResumeBankViewModel() /* { etc. } */

You might change the private/internal to public.

You may also wish to look at the other public constructors that are already defined and pass some appropriate values to one of them:

public ResumeBankViewModel() : this(value1, value2, value3) { }

Or make it's parameters optional:

public ResumeBankViewModel(object arg1 = value1, object arg2 = value2, object arg3 = value3)

Any of these might lead to more issues that you will need to work through, but one of these is the bare minimum to clear this error.

rfmodulator
  • 3,638
  • 3
  • 18
  • 22
1

Classic mapping works for mapping based on source members: https://docs.automapper.org/en/latest/Construction.html

If you cannot change the class (in contracts for example) having constructors with parameters that are different from members, you can use ConstructUsing.

You can use it like this to specify arguments :

Mapper.CreateMap<ObjectFrom, ObjectTo>()
    .ConstructUsing(x => new ObjectTo(arg0, arg1, etc));

Check the full answer here: Automapper - how to map to constructor parameters instead of property setters

Pierre
  • 490
  • 1
  • 7
  • 26
0

I got the this error when using a "wrong" access modifier, i.e. internal instead of public, when mapping between two classes.

jrn6270
  • 61
  • 11