2016-05-24 3 views
2

Так что проблема.Automapper, конфигурация сопоставления не сохраняется

Ive добавил

AutoMapperConfig.Configure(); 

к Application_Start в global.asax

он запускает код

Mapper.Initialize(x => 
{ 
    x.AddProfile<DomainToViewModelMappingProfile>(); 
    x.AddProfile<ViewModelToDomainMappingProfile>(); 
}); 

Mapper.AssertConfigurationIsValid(); 

, который работает

public class DomainToViewModelMappingProfile : Profile 
{ 
    protected override void Configure() 
    { 

     Mapper.CreateMap<DBO.User, ViewModels.UserViewModel>(); 
    } 
} 

и

public class ViewModelToDomainMappingProfile : Profile 
{ 
    protected override void Configure() 
    { 
     Mapper.Initialize(cfg => 
     { 
      cfg.CreateMap<ViewModels.UserViewModel, DBO.User>(); 
     }); 
    } 
} 

и все скомпилировано и работает нормально.

но в контроллере:

UserViewModel model = new UserViewModel(); 
User user = userService.GetUser(2); 
model = Mapper.Map<User, UserViewModel>(user); //this line fails as mapping doesnt exist 
return View(); 

но если я добавить отображение конфигурации в методе контроллера

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(); 

он работает отлично.

игнорировать различные синтаксисы с помощью automapper. Ive попробовал устаревший и новый способ картографирования и оба отказались.

Благодаря

+0

Почему в классе 'ViewModelToDomainMappingProfile' вы вызываете' CreateMap' внутри 'Initialize'? Наверное, это твоя проблема. – MaKCbIMKo

+0

из того, что я нашел в Интернете, это был новый способ создания сопоставлений, поскольку традиционный способ устарел. Как выясняется, это определенно проблема, поскольку традиционный способ работает, несмотря на то, что я сказал в уст, мои извинения. –

+0

Правильно, но похоже, что вы называете это дважды. И похоже, что 'ViewModelToDomainMappingProfile' переопределяет все предыдущее сопоставление (из' DomainToViewModelMappingProfile'), потому что он вызывает 'Initialize' – MaKCbIMKo

ответ

0

попытка переопределить «ProfileName»:

public class DomainToViewModelMappingProfile : Profile 
{ 
public override string ProfileName 
    { 
     get 
     { 
      return "DomainToViewModelMappingProfile"; 
     } 
    } 

protected override void Configure() 
{ 

    Mapper.CreateMap<DBO.User, ViewModels.UserViewModel>(); 
} 
} 
+0

Я тоже это пробовал, но, поскольку это не сработало, я проигнорировал его из вопроса –

+0

, можете ли вы поделиться пользовательским объектом и userViewModel? – Ahmado

0

ОК, спасибо MaKCbIMKo за указание мне в правильном направлении

Как описано я не должен инициализировать как его уже будучи сделано в automapperconfig.

Синтаксис один раз в профиле просто.

CreateMap<ViewModels.UserViewModel, DBO.User>(); 
+0

Пожалуйста, удалите этот «Ответ», добавьте свой результат в свой вопрос или в качестве комментария и отметьте ответ @MaKCbIMKo в качестве выигрышного ответа. – mxmissile

+0

Хорошо, подождите. Вы хотите, чтобы я исправил свой вопрос с помощью рабочего кода, который я нашел. Удалите мой ответ и пометьте makcblmko как ответ. (Никакое неуважение не предназначалось для главы, он был невероятно полезен), но это было полное решение, а не поиск того, что было неправильно. –

1

Проблема заключается в том, что вы вызываете Initialize метод внутри вашего Profile, что приводит к подменяют уже существовали отображения:

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>(); 
     }); 
    } 
} 

И здесь, у вас есть два пути:

Way № 1 (с использованием статического API - устаревший)

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 (с использованием экземпляра 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()); 

В пути № 2 вам нужно будет хранить вас Mapper конфигурацию где (статическое поле, DI), а затем использовать его внутри контроллера. Я хотел бы предложить ввести экземпляр Mapper в ваш контроллер (например, используя некоторый контейнер DI).

Надеюсь, это поможет.

Смежные вопросы