0

Jquery ajax post calls my WebMethod which gets external Web Service content, converts it and return to client.

My class: ConfiguratorModel : List<OptionGroup>.

Inside Application_Start: Mapper.CreateMap<choiceList, OptionGroup>() .

After CreateMap I also run Mapper.AssertConfigurationIsValid() successfully.

When executing Mapper.Map<List<choiceList>, ConfiguratorModel>(choiceLists) inside my Converter class, automapper fails and return following error as json to client:

{"Message":"TryingtomapSystem.Collections.Generic.List`1[[Constructor.OFML.Services.Basket.choiceList,Constructor.OFML,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null]]toConstructor.OFML.ConfiguratorModel.\nExceptionoftype\u0027AutoMapper.AutoMapperMappingException\u0027wasthrown.","StackTrace":"atAutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContextcontext)\r\natAutoMapper.MappingEngine.Map(Objectsource,TypesourceType,TypedestinationType)\r\natAutoMapper.MappingEngine.Map[TSource,TDestination](TSourcesource)\r\natAutoMapper.Mapper.Map[TSource,TDestination](TSourcesource)\r\natConstructor.OFML.ConfiguratorConverter.ConvertToConfiguratorModel(List`1choiceLists)inc:\\EPiServer\\Sites\\bouvet_sbe\\Constructor\\trunk7\\libraries\\Constructor.FOML\\ConfiguratorConverter.cs:line58\r\natConstructor.OFML.ConfiguratorConverter.BuildConfiguratorModel(List`1choiceLists,articleDataarticleData)inc:\\EPiServer\\Sites\\bouvet_sbe\\Constructor\\trunk7\\libraries\\Constructor.FOML\\ConfiguratorConverter.cs:line68\r\natConstructor.OFML.ConfiguratorConverter.BuildConfiguratorResultModel(List`1choiceLists,articleDataarticleData,StringimageUrl)inc:\\EPiServer\\Sites\\bouvet_sbe\\Constructor\\trunk7\\libraries\\Constructor.FOML\\ConfiguratorConverter.cs:line90\r\natConstructor.OFML.OfmlService.GetConfigurationResult(StringsessionId,StringarticleId)inc:\\EPiServer\\Sites\\bouvet_sbe\\Constructor\\trunk7\\libraries\\Constructor.FOML\\OfmlService.cs:line89\r\natConstructor.Services.ConfiguratorService.GetInitialJson(StringsessionId,StringarticleId)inc:\\EPiServer\\Sites\\bouvet_sbe\\Constructor\\trunk7\\www\\Services\\ConfiguratorService.asmx.cs:line32","ExceptionType":"AutoMapper.AutoMapperMappingException"}

If I move Mapper.CreateMap before Mapper.Map everything works like a charm. But CreateMap is not thread safe, running it each time is a bad workaround. Do you have any idea what I should do? My IIS is btw. running in full trust.

Goran
  • 19
  • 7
  • Why are you worried about thread safety in `Application_Start`.. ? Only a single thread will call it at a time. That is, unless you have some sort of strange IIS setup going on. – Simon Whitehead Jul 02 '13 at 10:48
  • "Mapper.CreateMap is not threadsafe, nor will it ever be. However, Mapper.Map is thread-safe. The Mapper static class is just a thin wrapper on top of the MappingEngine and Configuration objects. So only use Mapper.CreateMap if you do your configuration in one central place in a threadsafe manner." Ref: http://stackoverflow.com/questions/10649250/is-mapper-map-in-automapper-thread-safe – Goran Jul 02 '13 at 10:56
  • Therefor I want to run CreateMap just once. – Goran Jul 02 '13 at 10:58
  • `Application_Start` is called once, by a single thread, when the application fires up. Put `CreateMap` in there and your problem is solved.. – Simon Whitehead Jul 02 '13 at 10:59
  • That's the problem. If I put it there the exceptions kicks in. – Goran Jul 02 '13 at 10:59
  • My apologies. I misunderstood. I thought you were calling `Mapper.Map`, then `Mapper.CreateMap` in `Application_Start`.. which is the wrong way around (and `Mapper.Map` shouldn't be in there anyway!). Sorry. – Simon Whitehead Jul 02 '13 at 11:04
  • No worries, I appreciate you feedback either way. :) – Goran Jul 02 '13 at 11:05

1 Answers1

0

CreateMap location shouldn't be a problem as long as it is called in a static class.

Something like this should work:

 public static class AutoMapperConfiguration
 {
    public static void Configure()
    {
      ConfigureSomeMapping();
    }

    private static void ConfigureSomeMapping()
    {
       Mapper.CreateMap<...>();
     } 
  }

In Application_Start, call

 AutoMapperConfiguration.Configure();

You could also use AutoMapper profiles to make it cleaner.

rivarolle
  • 1,528
  • 11
  • 18