Try our conversational search powered by Generative AI!

How to use CategoryList property on Commerce Products/Variants

Vote:
 

Hi, I'm trying to add a property of type CategoryList to the model of a product on an epi commerce site, but receive the following exception stating that CategoryList cannot be mapped to a MetaDataType.

Does this mean Episerver CMS Categories are simply not compatible with Commerce products? How would I go about tagging Epi Commerce Products with Episerver CMS Categories?

I've added the property like so:
[Display(
Name = "Search Context",
Description = "Select the contexts you want your content to connect to",
GroupName = SystemTabNames.Content,
Order = 1)]
public virtual CategoryList SearchContext { get; set; }

Using Episerver 11.13.2.0
Episerver.Commerce 13.12.0:

[NotSupportedException: The type EPiServer.Core.CategoryList can not be mapped to a MetaDataType]
   EPiServer.Commerce.Catalog.Provider.Construction.MetaDataTypeResolver.GetMetaDataType(Type type) +409
   EPiServer.Commerce.Catalog.Provider.Construction.CatalogContentScannerExtension.CreateOrUpdateMetaField(MetaClass metaClass, PropertyDefinitionModel propertyDefinitionModel) +230
   EPiServer.Commerce.Catalog.Provider.Construction.CatalogContentScannerExtension.AssignModelPropertiesToMetaClass(MetaClass metaClass, IEnumerable`1 propertyDefinitionModels) +312
   EPiServer.Commerce.Catalog.Provider.Construction.CatalogContentScannerExtension.AssignValuesToProperties(ContentTypeModel contentTypeModel) +171
   EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelScanner.AssignValuesToProperties(ContentTypeModel modelType) +457
   EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelScanner.AddModel(Type type) +85
   EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelScanner.RegisterModels() +226
   EPiServer.Initialization.Internal.ModelSyncInitialization.Initialize(InitializationEngine context) +263
   EPiServer.Framework.Initialization.Internal.<>c__DisplayClass2_0.<Initialize>b__0() +19
   EPiServer.Framework.Initialization.Internal.ModuleNode.Execute(Action a, String key) +52
   EPiServer.Framework.Initialization.Internal.ModuleNode.Initialize(InitializationEngine context) +80
   EPiServer.Framework.Initialization.InitializationEngine.InitializeModules() +179

[InitializationException: Initialize action failed for Initialize on class EPiServer.Initialization.Internal.ModelSyncInitialization, EPiServer, Version=11.13.2.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7]
   EPiServer.Framework.Initialization.InitializationEngine.InitializeModules() +492
   EPiServer.Framework.Initialization.InitializationEngine.ExecuteTransition(Boolean continueTransitions) +153
   EPiServer.Framework.Initialization.InitializationEngine.Initialize() +40
   EPiServer.Framework.Initialization.<>c.<FrameworkInitialization>b__7_0(InitializationEngine e) +9
   EPiServer.Framework.Initialization.InitializationModule.EngineExecute(HostType hostType, Action`1 engineAction) +461
   EPiServer.Framework.Initialization.InitializationModule.FrameworkInitialization(HostType hostType) +170
   EPiServer.Global..ctor() +44
   OceanInsight.EPiServerApplication..ctor() in C:\Users\dshinn\source\repos\OceanTransition\OceanInsight\Global.asax.cs:29
   ASP.global_asax..ctor() +56

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
   System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +122
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +239
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +85
   System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark) +1173
   System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) +130
   System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture) +21
   System.Web.HttpRuntime.CreateNonPublicInstance(Type type, Object[] args) +59
   System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +148
   System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +303

[HttpException (0x80004005): Exception has been thrown by the target of an invocation.]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +659
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +89
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +189



#245594
Edited, Dec 15, 2020 19:30
Vote:
 

Hi David,

Try the EditorDescriptor & Attributes for the CategoryList property.

https://getadigital.com/no/blogg/improved-categorylist-editor-descriptor-for-episerver/

#245620
Dec 16, 2020 8:06
Vote:
 

You would need a backing type so Commerce knows how to map your property to one of its internal types. But is there a reason you can't use IList<T> instead? (I'm not familiar with CategoryList) 

[BackingType(typeof(PropertyIntegerList))]
public virtual IList<int> IntegerList { get; set; }

instead? 

#245622
Dec 16, 2020 9:14
Vote:
 

@Sanjay this still requires the property be a CategoryList, which throws the same NotSupportedException.

@Quan an int list does not provide the editor with the ability to select from a list of the Admin defined Category values, therefore it is not sufficient. 

The category list should look like this on the Commerce Product: https://imgur.com/a/KQfWKNU

Surely this is not limited to only the CMS?

#245630
Edited, Dec 16, 2020 15:41
Vote:
 

I see. You can technically try out with this attribute

[BackingType(typeof(PropertyString))]

Untested obviously so I'm not sure if it works. CategoryList overrides ToString to create a joined list with , separator so it might ... 

#245632
Dec 16, 2020 15:54
Vote:
 

In Episerver Commerce.Core (13.19.0) I am able to create the below the property.

public virtual CategoryList SearchContext { get; set; }

#245634
Dec 16, 2020 16:14
Vote:
 

Thank you for showing that it's possible Sanjay!

I've upgraded to the latest version of Commerce and am getting the same exception. Are there perhaps other settings that dictate what properties can and cannot be added?

#245688
Dec 17, 2020 15:34
Vote:
 

@Sanjay can you confirm that is a product in your screenshot? It looks like the tabs belong to a page, not a product type inheriting from Episerver Commerce's base ProductContent type, which has the "Belongs To",  "Variants", "Assets", etc tabs, which is where the issue occurs.

@Quan the PropertyString backing type throws a TypeMismatchException when it is applied to a property that is not of type string.

#245932
Dec 22, 2020 1:12
Vote:
 

Yes, that is confirmed the tabs belong to a page, not a product.

Can try to inherit ICategorizable interface on your page?

e.g.:

public interface IPage : IContent, ICategorizable {}

public class MyPage : PageData, IPage{}

#245942
Dec 22, 2020 9:01
Vote:
 

The ProductContent base class implements ICategorizable, but the Categories field hooks in to a different Commerce Category system than the CMS.

It also doesn't seem to allow you to add multiple fields of type Category to a single product. If you do, the UI doesn't allow you to add categories to the new Categories property: https://imgur.com/P0EkdkP

We were hoping to add multiple category fields that could be used as distinct Facets in an Epi Find search app. I suppose we could try adding a multi select checkbox with a selection factory that pulls the list of categories as a workaround. Would love to see this work out of the box.

#245981
Dec 23, 2020 18:05
Vote:
 

The ProductContent base class implements ICategorizable, but the Categories field hooks in to a different Commerce Category system than the CMS.

It also doesn't seem to allow you to add multiple fields of type Category to a single product. If you do, the UI doesn't allow you to add categories to the new Categories property: https://imgur.com/P0EkdkP

We were hoping to add multiple category fields that could be used as distinct Facets in an Epi Find search app. I suppose we could try adding a multi select checkbox with a selection factory that pulls the list of categories as a workaround. Would love to see this work out of the box.

#245982
Dec 23, 2020 18:05
Pierre Vignon (Yaksa) - Sep 26, 2023 12:22
We are encountering the same issue. We would also love to have CategoryList properly handled by default in Commerce for Catalog Objects (as Pages or Blocks in the CMS),
* 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.