Reputation: 2921
I'm just starting to learn AutoMapper in an MVC project. I have a base entity "Attendee" with a string field for Gender (possible values of "M" or "F").
I already have a basic mapping created between my Attendee and my AttendeeEditView objects. What I want to do is convert the "M" or "F" Gender string on the model side to a SelectList on the ViewModel side, with the appropriate value selected in the list.
I think I need a ValueResolver to do this... here's what I've written:
public class GenderMenuResolver : ValueResolver<Attendee, SelectList> {
protected override SelectList ResolveCore( Attendee source ) {
List<object> items = new List<object>(){
new{ Value = "F" , Text = "Female" },
new{ Value = "M" , Text = "Male" }
};
string Gender = source.Gender ?? "";
string selectedValue = new List<string>() { "M", "F" }.Contains( Gender.ToUpper() ) ? Gender.ToUpper() : "";
SelectList GenderMenu = new SelectList(
items,
"Value",
"Text",
selectedValue
);
return GenderMenu;
}
}
And my mapping code:
Mapper.CreateMap<Attendee, AttendeeEditView>()
.ForMember( dest => dest.Gender, opt => opt.ResolveUsing<GenderMenuResolver>() );
List<AttendeeEditView> ViewModel = Mapper.Map<List<AttendeeEditView>>( Attendees );
stepping through I can see this code executes and outputs a proper selectlist. However, I get the following error:
Mapping types: SelectList -> SelectList System.Web.Mvc.SelectList -> System.Web.Mvc.SelectList
Destination path: List`1[0].Gender.Gender
Source value: System.Web.Mvc.SelectList
First, the ".Gender.Gender" mapping seems incorrect.
But what appears to the root issue... an inner exception message reveals this:
"Type 'System.Web.Mvc.SelectList' does not have a default constructor"
Can anyone help me identify what I'm doing wrong, or perhaps a better approach I should be using? Thanks.
Upvotes: 2
Views: 2165
Reputation: 239440
I think you're making this more difficult than it needs to be. Not everything needs to be mapped, in fact things like SelectList
s almost certainly shouldn't be mapped because they're only relevant to a view model, not a model.
So, in your view model just do something like:
public string Gender { get; set; }
public SelectList GenderChoices
{
get
{
return new SelectList(new List<SelectListItem>
{
new SelectListItem { Value = "M", Text = "Male" },
new SelectListItem { Value = "F", Text = "Female" }
}, "Value", "Text", Gender);
}
}
Where Gender
would be mapped, but GenderChoices
would just exist on your view model.
Then, in your view:
@Html.DropDownListFor(m => m.Gender, Model.GenderChoices)
Upvotes: 12