Hi
I'm no automapper expert, but by looking at the stack trace it looks like the ValidUrlAttribute constructor is called before the IoC container has been configured. And for the default constructor on ValidUrlAttribute to work, it needs the container to be configured. If it isn't, you need to use the constructor with takes two services as arguments, and pass those on explicitly.
Now, I understand that it is automapper who does this call, and not you explicitly. But would it be possible to do this logic later in the initialization, when the container is all setup and ready to be used?
Regards
Per Gunsarfs
Thank you team,
Quan,
Below is out code.we have faced some issues regarding the web API route registration so registered directly in dependency module instead of app_start. The commented line of code has a problem.
[InitializableModule] [ModuleDependency(typeof(EPiServer.Web.InitializationModule))] public class DependencyResolverInitialization : IConfigurableModule { public void ConfigureContainer(ServiceConfigurationContext context) { context.StructureMap().Configure(ConfigureContainer); var dependencyResolver = new StructureMapDependencyResolver(context.StructureMap()); DependencyResolver.SetResolver(dependencyResolver); ////mvc GlobalConfiguration.Configure(config => { WebApiConfig.Register(config); config.Services.Add(typeof(IExceptionLogger), new WebApiExceptionLogger()); }); GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver; ////web api } public void Initialize(InitializationEngine context) { } public void Uninitialize(InitializationEngine context) { } public void Preload(string[] parameters) { } private static void ConfigureContainer(ConfigurationExpression container) { container.Scan(opt => { opt.TheCallingAssembly(); opt.WithDefaultConventions(); opt.LookForRegistries(); }); container.For<UserManager<ApplicationUser>>() .Use(() => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))) .SetLifecycleTo(new UniquePerRequestLifecycle()); container.For<RoleManager<IdentityRole>>() .Use(() => new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()))) .SetLifecycleTo(new UniquePerRequestLifecycle()); container.For<ICacheServiceFactory>() .Use(() => new CacheServiceFactory(HttpContext.Current)); container.For<ICustomerRepository>().Use<CustomerRepository>(); container.For<IWLCUsersRepository>().Use<WLCUsersRepository>(); container.For<IUnitOfWork>().Use<UnitOfWork>(); container.For<SnsDbContext>().HybridHttpOrThreadLocalScoped().Use<SnsDbContext>(); container.For(typeof(IRepository<>)).Use(typeof(GenericRepository<>)); container.For<IMapper>().Use(new Mapper(GetMappingConfiguration())); } private static MapperConfiguration GetMappingConfiguration() { var mapperConfiguration = new MapperConfiguration(cfg => { cfg.ConstructServicesUsing(type => ServiceLocator.Current.GetInstance(type)); cfg.CreateMap<string, IndexSearchableStringsArray>() .ForMember(x => x.Value, opt => opt.MapFrom(src => src == null ? null : src.Split(',').Where(x => !string.IsNullOrEmpty(x)).Select(x => x.Trim()))) .ForMember(x => x.SearchTerm, opt => opt.MapFrom(src => src == null ? null : src.Split(',').Where(x => !string.IsNullOrEmpty(x)).Select(x => SearchHelper.RemoveSpecialSearchCharacters(x, false).Trim()))) .ForMember(x => x.Values, opt => opt.MapFrom(src => SearchHelper.GetSearchableValuesString(src))); cfg.CreateMap<string, IndexSearchableString>() .ForMember(x => x.SearchTerm, opt => opt.MapFrom(x => SearchHelper.RemoveSpecialSearchCharacters(x, false))) .ForMember(x => x.Value, opt => opt.MapFrom(x => x)); cfg.CreateMap<OrderResponseListItem, SnSOrderListViewModel>() .ForMember(dest => dest.OrderDateTime, opt => opt.MapFrom(src => src.OrderDateTime.ToString("dd-MMM-yyyy"))); cfg.CreateMap<EpiOrderResponseListItem, WLC.Models.ViewModels.WLCOrderListViewModel>() .ForMember(dest => dest.OrderDateTime, opt => opt.MapFrom(src => src.OrderDateTime.ToString("dd-MMM-yyyy"))); cfg.CreateMap<OrderResponseDetail, OrderDetailPageViewModel>() .ForMember(x => x.Items, order => order.Ignore()) .IgnoreAllNonExistingProperties(); cfg.CreateMap<OrderResponseDetail, WLC.Models.ViewModels.WLCOrderDetailPageViewModel>() .ForMember(x => x.Items, order => order.Ignore()) .IgnoreAllNonExistingProperties(); cfg.CreateMap<OrderResponseDetailPart, SnSOrderDetailItemViewModel>() .IgnoreAllNonExistingProperties(); cfg.CreateMap<OrderResponseDetailPart, WLC.Models.ViewModels.WLCOrderDetailItemViewModel>() .IgnoreAllNonExistingProperties(); //// cfg.CreateMap<ImportProductData, Variation>() //// .ForMember(dest => dest.Orientation, opt => opt.Ignore()) //// .ForMember(dest => dest.Series, opt => opt.Ignore()) //// .ForMember(dest => dest.Tested, opt => opt.Ignore()) //// .ForMember(dest => dest.Rotation, opt => opt.Ignore()) //// .ForMember(dest => dest.Material, opt => opt.Ignore()) //// .IgnoreAllNonExistingProperties(); cfg.CreateMap<Variation, ExportProductData>() .ForMember(x => x.Orientation, opt => opt.MapFrom(src => EnumValues.Convert<OrientationOptionsEnum>(src.Orientation))) .ForMember(x => x.Series, opt => opt.MapFrom(src => EnumValues.Convert<SeriesOptionsEnum>(src.Series))) .ForMember(x => x.Tested, opt => opt.MapFrom(src => EnumValues.Convert<TestedOptionsEnum>(src.Tested))) .ForMember(x => x.Rotation, opt => opt.MapFrom(src => EnumValues.Convert<RotationOptionsEnum>(src.Rotation))) .ForMember(x => x.Material, opt => opt.MapFrom(src => EnumValues.Convert<MaterialOptionsEnum>(src.Material))) .ForMember(x => x.Specifications3, opt => opt.MapFrom(src => src.Applications)) .IgnoreAllNonExistingProperties(); }
Thanks and Regards,
Karthik.
It seems to me that at that point there is no registration for UrlSegmentOptions
if you add context.Locate.Advanced.GetInstance<UrlSegmentOptions>(); inside Initialize, what does it return?
If it returns null, then you might try to add it
context.Services.AddSingleton(s => new UrlSegmentOptions
{
SupportIriCharacters = true,
ValidCharacters = @"\p{L}0-9\-_~\.\$"
});
Thanks for your quick reply Quan,
I tried this both but getting the same error.
public void ConfigureContainer(ServiceConfigurationContext context) { context.StructureMap().Configure(ConfigureContainer); var dependencyResolver = new StructureMapDependencyResolver(context.StructureMap()); DependencyResolver.SetResolver(dependencyResolver); ////mvc GlobalConfiguration.Configure(config => { WebApiConfig.Register(config); config.Services.Add(typeof(IExceptionLogger), new WebApiExceptionLogger()); }); GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver; ////web api } public void Initialize(InitializationEngine context) { context.Locate.Advanced.GetInstance<UrlSegmentOptions>(); }
Hi Quan,
We are calling our mapper set up inside the below method.
public void ConfigureContainer(ServiceConfigurationContext context)
{
}
We can't hit the Initialization method since the Custom Model class to EPiServer Model class mapping throws an exception which calls inside the ConfigureContainer. If we commented out the below mapper set up we can get a value(non Null) for the context.Locate.Advanced.GetInstance<UrlSegmentOptions>() in Initialization call.
//// cfg.CreateMap<ImportProductData, Variation>()
//// .ForMember(dest => dest.Orientation, opt => opt.Ignore())
//// .ForMember(dest => dest.Series, opt => opt.Ignore())
//// .ForMember(dest => dest.Tested, opt => opt.Ignore())
//// .ForMember(dest => dest.Rotation, opt => opt.Ignore())
//// .ForMember(dest => dest.Material, opt => opt.Ignore())
//// .IgnoreAllNonExistingProperties();
We also try to Initialize the URLSegmentOption before the mapper set up did not help us.
public void ConfigureContainer(ServiceConfigurationContext context)
{
context.Services.AddSingleton(s => new UrlSegmentOptions
{
SupportIriCharacters = true,
ValidCharacters = @"\p{L}0-9\-_~\.\$"
});
context.StructureMap().Configure(ConfigureContainer); // Mappers setup call
var dependencyResolver = new StructureMapDependencyResolver(context.StructureMap());
DependencyResolver.SetResolver(dependencyResolver); ////mvc
GlobalConfiguration.Configure(config =>
{
WebApiConfig.Register(config);
config.Services.Add(typeof(IExceptionLogger), new WebApiExceptionLogger());
});
GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver; ////web api
}
My bad, I should be more clear, when I talked about adding this code
context.Services.AddSingleton(s => new UrlSegmentOptions { SupportIriCharacters = true, ValidCharacters = @"\p{L}0-9\-_~\.\$" });
I meant ConfigureContainer, before
context.StructureMap().Configure(ConfigureContainer);
Thanks Quan,
Sorry for the late reply.I am not able to get you. Please explain what to do.
Hi valdis iljuconoks,
we are using below one
<package id="AutoMapper" version="7.0.1" targetFramework="net461" />
I have the exact same problem. How did you solve it? I tried the suggestions in this thread without success.
I am not able to resolve the issue(when registering in the dependency module). So i used like below one
private IMapper Map
{
get { return map ?? (map = CreateMap()); }
}
private IMapper CreateMap()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<ImportProductData, Variation>()
.ForMember(dest => dest.Orientation, opt => opt.Ignore())
.IgnoreAllNonExistingProperties();
});
return config.CreateMapper();
}
Hi,
We are using AutoMapper in our Commerce site. While mapping from the custom model to an EPiServer Model(VariationContent) throws a below error.
Adding to that vice versa works properly. Also In version 10.2.1 works well, but not in 12.4.
I have mentioned the codes below with an error.
Please help me out,
Advance thanks,
regards,
Karthik