Reputation: 1002
So the problem.
Ive added
AutoMapperConfig.Configure();
to the application_Start in global.asax
it runs the code
Mapper.Initialize(x =>
{
x.AddProfile<DomainToViewModelMappingProfile>();
x.AddProfile<ViewModelToDomainMappingProfile>();
});
Mapper.AssertConfigurationIsValid();
which runs
public class DomainToViewModelMappingProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<DBO.User, ViewModels.UserViewModel>();
}
}
and
public class ViewModelToDomainMappingProfile : Profile
{
protected override void Configure()
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ViewModels.UserViewModel, DBO.User>();
});
}
}
and everything compiles and runs fine.
but in the controller:
UserViewModel model = new UserViewModel();
User user = userService.GetUser(2);
model = Mapper.Map<User, UserViewModel>(user); //this line fails as mapping doesnt exist
return View();
but if i add the mapping config in the controller method
Mapper.CreateMap<ViewModels.UserViewModel,DBO.User>();
UserViewModel model = new UserViewModel();
User user = userService.GetUser(2);
model = Mapper.Map<User, UserViewModel>(user); //Works great
return View();
it works fine.
ignore the different syntax with automapper. Ive tried the deprecated and new way of mapping and both fail.
Thanks
Upvotes: 2
Views: 1584
Reputation: 2820
The problem is that you're calling Initialize
method inside your Profile
which leads to overriding your already existed mappings:
public class ViewModelToDomainMappingProfile : Profile
{
protected override void Configure()
{
// you should not to call Initialize method inside your profiles.
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ViewModels.UserViewModel, DBO.User>();
});
}
}
And here, you have two ways:
Way #1 (using the static API - deprecated)
public class DomainToViewModelMappingProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<DBO.User, ViewModels.UserViewModel>();
}
}
public class ViewModelToDomainMappingProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<ViewModels.UserViewModel, DBO.User>();
}
}
// initialize your mapper by provided profiles
Mapper.Initialize(x =>
{
x.AddProfile<DomainToViewModelMappingProfile>();
x.AddProfile<ViewModelToDomainMappingProfile>();
});
Mapper.AssertConfigurationIsValid();
Way #2 (using the instance API)
// in this case just call CreateMap from Profile class - its the same as CreateMap on `cfg`
public class DomainToViewModelMappingProfile : Profile
{
public DomainToViewModelMappingProfile()
{
CreateMap<DBO.User, ViewModels.UserViewModel>();
}
}
public class ViewModelToDomainMappingProfile : Profile
{
public ViewModelToDomainMappingProfile()
{
CreateMap<ViewModels.UserViewModel, DBO.User>();
}
}
// initialize you mapper config
var config = new MapperConfiguration(cfg => {
cfg.AddProfile<DomainToViewModelMappingProfile>();
cfg.AddProfile<ViewModelToDomainMappingProfile>();
});
// and then use it
var mapper = config.CreateMapper();
// or
var mapper = new Mapper(config);
var dest = mapper.Map<Source, Dest>(new Source());
In the Way #2 you will need to store you mapper configuration somewhere (static field, DI), and then use it inside your controller. I would like to suggest to inject the Mapper
instance into your controller (e.g. using some DI container).
Hope it will help.
Upvotes: 1
Reputation: 1002
OK, thanks to MaKCbIMKo for pointing me in the right direction
As described i dont have to initialize as its already being done in the automapperconfig.
the syntax once in the profile is simply.
CreateMap<ViewModels.UserViewModel, DBO.User>();
Upvotes: 0
Reputation: 58
try to override "ProfileName" :
public class DomainToViewModelMappingProfile : Profile
{
public override string ProfileName
{
get
{
return "DomainToViewModelMappingProfile";
}
}
protected override void Configure()
{
Mapper.CreateMap<DBO.User, ViewModels.UserViewModel>();
}
}
Upvotes: 0