I upgraded Umbraco from 6.1.4 to 7.2.0 and once I connected it to my logic layer I encounter an issue with Automapper.
Received an error from the server
Server call failed for getting current user
Missing type map configuration or unsupported mapping.
Mapping types:
User -> UserDetail
Umbraco.Core.Models.Membership.User -> Umbraco.Web.Models.ContentEditing.UserDetail
Destination path:
UserDetail
Source value:
Umbraco.Core.Models.Membership.User
EXCEPTION DETAILS:
AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
Mapping types:
User -> UserDetail
Umbraco.Core.Models.Membership.User -> Umbraco.Web.Models.ContentEditing.UserDetail
Destination path:
UserDetail
Source value:
Umbraco.Core.Models.Membership.User
STACKTRACE:
at Umbraco.Web.Editors.AuthenticationController.GetCurrentUser()
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.<GetExecutor>b__c(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<>c__DisplayClass5.<ExecuteAsync>b__4()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)
I already register Automapper for my models and I suspect that my initialization of the mapper is short circuiting the Umbraco implementation of it.
What needs to be done to use my own mappings in addition to the Umbraco ones?
It looks like Umbraco.Core.CoreBootManager is responsible initialzing the models that are required for the back office. Currently researching if I can inherit MapperConfiguration and see if Umbraco will pick them up and work correctly.
I too am having this issue - is there a way I can use my own mappings with the Umbraco ones? Code similar to below - I have a feeling its doing something funny on ApplicationStarted. Anyone have any ideas?
So after further investigation, we found you shouldn't use Mapper.Initialize as this bins anything that has gone before it - we went down the path of the way Umbraco set their mappings up.
In each mapping profile, we implemented the IMapperConfiguration interface, then in the ConfigureMappings we create our map like so:
public void ConfigureMappings(IConfiguration config, ApplicationContext applicationContext) { config.CreateMap<PaymentAttempt, AuthRequestBlock>().ConvertUsing<AuthRequestBlockTypeConverter>(); }
So just to summarize: I need to ditch all profiles, and hook up the mapping through IMapperConfigurations instead?
That kind of sucks, because I want all my assemblies to be responsible for registering their own mappings, without them knowing anything about Umbraco. That's kind of the idea about mapping profiles in the first place, isn't it?
Anyways, I'll figure something out.
EDIT
Seems like I was a bit to fast in drawing conclussions there. I was actually able to fix it pretty easily by inherriting MapperConfiguration and moving my original code to load the profiles to ConfigureMappings(IConfiguration config, ApplicationContext applicationContext).
So that means I can still use my original Profiles and leave each assembly in charge of it's own mappings.
On a side note
In newer versions of AutoMapper (sadly unsupported by Umbraco 7) AutoMapper.IConfiguration has a nifty method AddProfiles(IEnumerable<Assembly> assembliesToScan), which basically loads all profiles from the assemblies you pass in. I pulled the code from the Automapper code base and added it, with some minor changes, as an extension method. Might be of use, so here it goes:
internal static class IConfigurationExtensions
{
//from automapper v7 (https://github.com/AutoMapper/AutoMapper)
public static void AddProfiles(this IConfiguration me, IEnumerable<Assembly> assembliesToScan)
{
var allTypes = assembliesToScan.Where(a => !a.IsDynamic).SelectMany(a => a.DefinedTypes).ToArray();
var profiles =
allTypes
.Where(t => typeof(Profile).GetTypeInfo().IsAssignableFrom(t))
.Where(t => !t.IsAbstract)
.Select(t => t.AsType());
foreach (var profile in profiles)
{
me.AddProfile((Profile)Activator.CreateInstance(profile));
}
}
}
Automapper in 7 failing on backoffice
I upgraded Umbraco from 6.1.4 to 7.2.0 and once I connected it to my logic layer I encounter an issue with Automapper.
Received an error from the server
Server call failed for getting current user
Missing type map configuration or unsupported mapping. Mapping types: User -> UserDetail Umbraco.Core.Models.Membership.User -> Umbraco.Web.Models.ContentEditing.UserDetail Destination path: UserDetail Source value: Umbraco.Core.Models.Membership.User
EXCEPTION DETAILS:
AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping. Mapping types: User -> UserDetail Umbraco.Core.Models.Membership.User -> Umbraco.Web.Models.ContentEditing.UserDetail Destination path: UserDetail Source value: Umbraco.Core.Models.Membership.UserSTACKTRACE:
I already register Automapper for my models and I suspect that my initialization of the mapper is short circuiting the Umbraco implementation of it.
What needs to be done to use my own mappings in addition to the Umbraco ones?
I have confirmed that removing my call when initializing Automapper indeed allows the backoffice to function. Here is an example of the call:
On application startup:
This will call an Automapper class that will setup all my mappings.
Here is an example of the map call for SocialNetwork.
It looks like Umbraco.Core.CoreBootManager is responsible initialzing the models that are required for the back office. Currently researching if I can inherit MapperConfiguration and see if Umbraco will pick them up and work correctly.
The issue was one of three things.
Startup was changed to because adding a profile seemed to clash with something.
RegisterAutoMapper.PopulateAutoMapper();
Took away inheriting profile since I was no longer using the initialize add profile any longer. Also had to remove the following:
The AssertConfiguartionIsValid caused issues no matter what.
Working modifications to original post below
This no longer appears to be an issue for me.
* Bump
Hey,
I too am having this issue - is there a way I can use my own mappings with the Umbraco ones? Code similar to below - I have a feeling its doing something funny on ApplicationStarted. Anyone have any ideas?
Thanks
Hey,
So after further investigation, we found you shouldn't use Mapper.Initialize as this bins anything that has gone before it - we went down the path of the way Umbraco set their mappings up.
In each mapping profile, we implemented the IMapperConfiguration interface, then in the ConfigureMappings we create our map like so:
Hope that helps someone! :)
K
Or
MapperConfiguration
if you prefer the abstract class route to the interface. That is an IMapperConfiguration anyway.https://github.com/umbraco/Umbraco-CMS/blob/7ee510ed386495120666a78c61497f58ff05de8f/src/Umbraco.Core/Models/Mapping/MapperConfiguration.cs
Running into a similar issue here.
So just to summarize: I need to ditch all profiles, and hook up the mapping through IMapperConfigurations instead?
That kind of sucks, because I want all my assemblies to be responsible for registering their own mappings, without them knowing anything about Umbraco. That's kind of the idea about mapping profiles in the first place, isn't it?
Anyways, I'll figure something out.
EDIT
Seems like I was a bit to fast in drawing conclussions there. I was actually able to fix it pretty easily by inherriting
MapperConfiguration
and moving my original code to load the profiles toConfigureMappings(IConfiguration config, ApplicationContext applicationContext)
.So that means I can still use my original Profiles and leave each assembly in charge of it's own mappings.
On a side note
In newer versions of AutoMapper (sadly unsupported by Umbraco 7)
AutoMapper.IConfiguration
has a nifty methodAddProfiles(IEnumerable<Assembly> assembliesToScan)
, which basically loads all profiles from the assemblies you pass in. I pulled the code from the Automapper code base and added it, with some minor changes, as an extension method. Might be of use, so here it goes:is working on a reply...