Try our conversational search powered by Generative AI!

Commerce 7.5 SEO Url routing problem with duplicating pageTypeNames

Vote:
 

I have more than one StartPage, but in different namespaces, when commerce 7.5 (7.6.1) SEO url is beeing resolved commerce tries to load all content types and fails when finds second StartPage with exception:

[SynchronizationException: More than one content model is assigned the metadata class name StartPage]
   EPiServer.Commerce.Catalog.Provider.MetaClassToContentTypeMap.ThrowIfNotUnique(Dictionary`2 mappings, String metaClassName) +114
   EPiServer.Commerce.Catalog.Provider.MetaClassToContentTypeMap.PopulateMetadataMappings() +341
   EPiServer.Commerce.Catalog.Provider.MetaClassToContentTypeMap.get_ContentTypeToMetaClassMapping() +111
   EPiServer.Commerce.Catalog.Provider.MetaClassToContentTypeMap.GetContentTypeModel(Int32 metaClassId) +233
   EPiServer.Commerce.Catalog.Provider.Construction.MetaClassContentFactory.Create(String baseEntryType, Int32 metaClassId, String language, Nullable`1 catalogId) +218
   EPiServer.Commerce.Catalog.Provider.Construction.EntryBuilder.GetCatalogContent(String entryType, Int32 metaClassId, String language, Int32 catalogId) +67
   EPiServer.Commerce.Catalog.Provider.Construction.EntryBuilder.ConstructEntries(CatalogEntryDto entryDto, String language) +196
   EPiServer.Commerce.Catalog.Provider.Construction.EntryBuilder.Create(IList`1 contentLinks, String language) +350
   EPiServer.Commerce.Catalog.Provider.CatalogContentLoader.GetContentFromBuilder(String language, IEnumerable`1 linkByType) +520
   EPiServer.Commerce.Catalog.Provider.CatalogContentLoader.GetItems(IList`1 contentLinks, String language, IMarket market) +634
   EPiServer.Commerce.Catalog.Provider.CatalogContentDraftStore.GetCommittedContents(IList`1 contentLinks, String language) +76
   EPiServer.Commerce.Catalog.Provider.CatalogContentDraftStore.GetItems(IList`1 contentLinks, String language) +396
   EPiServer.Commerce.Catalog.Provider.CatalogContentProvider.LoadContents(IList`1 contentReferences, ILanguageSelector selector) +233
   EPiServer.Commerce.Catalog.Provider.CatalogContentProvider.LoadContent(ContentReference contentLink, ILanguageSelector languageSelector) +264
   EPiServer.Core.<>c__DisplayClass1c.<LoadContentFromCacheOrRepository>b__1a() +141
   EPiServer.Core.OptimisticCache`1.Read(String cacheKey, ReadAndCacheObject`1 readAndCacheObject) +1175
   EPiServer.Core.ContentProvider.LoadContentFromCacheOrRepository(ContentReference contentreference, ILanguageSelector selector) +945
   EPiServer.Core.ContentProvider.Load(ContentReference contentLink, ILanguageSelector selector) +233
   EPiServer.DataFactory.TryGet(ContentReference contentLink, ILanguageSelector languageSelector, T& content) +526
   EPiServer.DataFactory.Get(ContentReference contentLink, ILanguageSelector languageSelector) +86
   EPiServer.Commerce.Routing.SeoUriRouter.GetRouteValues(String urlSegment, ContentReference routeRoot, SegmentContext segmentContext) +611
   EPiServer.Web.Routing.Segments.SimpleAddressSegmentRouter.ResolveContentForIncoming(ContentReference contentlink, String urlSegment, SegmentContext context) +245
   EPiServer.Web.Routing.Segments.SimpleAddressSegment.GetIncomingNode(ContentReference contentLink, SegmentContext context) +98
   EPiServer.Web.Routing.Segments.SimpleAddressSegment.RouteDataMatch(SegmentContext context) +81
   EPiServer.Web.Routing.ContentRoute.MatchSegments(SegmentContext segmentContext) +64
   EPiServer.Web.Routing.ContentRoute.RouteSegmentContext(SegmentContext segmentContext) +16
   EPiServer.Web.Routing.ContentRoute.GetRouteData(HttpContextBase httpContext) +481
   System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext) +251
   System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +79
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +165

populateMetadataMappings code looks like this:

        private Dictionary<Type, string> PopulateMetadataMappings()
        {
            _log.DebugBeginMethod("PopulateMetadataMappings", new object[0]);
            Dictionary<Type, string> mappings = new Dictionary<Type, string>();
            foreach (ContentTypeModel model in this._contentTypeModelRepository.List())
            {
                string metaClassName = model.get_ModelType().get_Name();
                CatalogContentTypeAttribute attribute = null;
                if (model.get_Attributes().TryGetSingleAttribute<CatalogContentTypeAttribute>(ref attribute) && !string.IsNullOrWhiteSpace(attribute.MetaClassName))
                {
                    metaClassName = attribute.MetaClassName;
                }
                this.ThrowIfNotUnique(mappings, metaClassName);
                mappings.Add(model.get_ModelType(), metaClassName);
            }
            return mappings;
        }

    

        protected virtual void ThrowIfNotUnique(Dictionary<Type, string> mappings, string metaClassName)
        {
            if (mappings.ContainsValue(metaClassName))
            {
                throw new SynchronizationException(string.Format("More than one content model is assigned the metadata class name {0}", metaClassName));
            }
        }

    

As it does not take into account namespaces, names overlap and YSOD is thrown.

 

Note: needed content type that renders commerce variations comes first in response from - this._contentTypeModelRepository.List()

 

Should commerce load all content types?

Is something wrong with my code?(Except that I have pageTypeNames with the same names in multiple namespaces)

Any ideas!

 

    

 

#85293
Apr 22, 2014 15:30
Vote:
 

I can confirm that renaming all page types so names would not overlap did the trick, and now commerce product friendly Urls work, but this seems like a problem with new EPiServer Commerce code, because as far as I understand it is allowed to have two page types with the same page type name(because they will have different namespaces and GUIDs), but if you do so you will have this problem.

#85303
Apr 22, 2014 18:20
Vote:
 

Renaming the contenttype classnames worked for us as well. 

If the contenttypes lives in different namespaces, but have the same classname this code still breaks, so the classnames have to be changed.
And this is not just the commerce specific (Catalog)contenttypes you must change the names of, the conflicting (CMS specific) contenttypes must be changed as well.

#113447
Edited, Nov 20, 2014 16:33
Vote:
 

Hi

This sounds like a bug to me. The unique metaclass name validation should not take content types from cms into consideration.

However, when we validate the name among the catalog content types we cannot take the namespace into consideration. The reason for that is that if you don't explicitly set a meta class name on your content type, we will use the class name as the name for the meta class (the backing store for catalog data). If you want to have two catalog content types with the same name in different namespaces you will need to set a unique MetaClassName on their CatalogContentTypeAttribute. But as I said, we shouldn't care about CMS specific content types when validating.

I've reported a bug for this:

#119804: Unique meta class validation for catalog content types validates against non catalog content types

Regards

Per Gunsarfs

#113487
Nov 21, 2014 14:05
Vote:
 

I agree, it would be really convenient that next time I migrate some old EPiServer instance to latest, I would not need to do either of these things

#113489
Nov 21, 2014 14:22
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.