LinkItem and PropertyList

Vote:
 

I'm trying to add a LinkItem property to a PropertyList type (I can't use LinkItemCollection as I need more properties on each item), but this fails during block creation and results in a stack overflow (stack trace can be found further below).

I've set up a basic example in a new Alloy project on the latest CMS version (12.22.4), and the block type looks like this:

[ContentType(DisplayName = "Example block", GUID = "de1b6876-c408-4283-a748-6ede69cd860b")]
public class ExampleBlock : BlockData
{
    [EditorDescriptor(EditorDescriptorType = typeof(CollectionEditorDescriptor<ExampleListItem>))]
    public virtual IList<ExampleListItem> Items { get; set; }
}

And the item type looks like this:

public class ExampleListItem
{
    public LinkItem Link { get; set; }
}

I've also set up a basic property definition for this (empty class inheriting PropertyList<ExampleListItem>).

This setup fails instantly once you create a new block in a content area and select the ExampleBlock type.

I've also tried decorating the LinkItem property with [JsonConverter(typeof(SystemTextLinkItemConverter))] (using the System.Text.Json.Serialization namespace for the attribute), as I believe Url properties require the same approach in PropertyLists, but this does not help in this case.

Is there anything I'm missing here, or a possible workaround to get this to work?

Part of the stack trace (last few rows keep piling up):

Stack overflow.
   at System.Reflection.RuntimeAssembly.GetCodeBase(System.Runtime.CompilerServices.QCallAssembly, System.Runtime.CompilerServices.StringHandleOnStack)
   at System.Reflection.RuntimeAssembly.GetCodeBase()
   at System.Reflection.RuntimeAssembly.GetName(Boolean)
   at EPiServer.Shell.ObjectEditing.Internal.TypeSerializer.GetAssemblyTypeNameWithoutVersion(System.Type)
   at EPiServer.Shell.ObjectEditing.Internal.EditorDefinitionRepository.GetEditorDefinitionDDSO(System.Type, System.String)
   at EPiServer.Shell.ObjectEditing.Internal.EditorDefinitionRepository.Get(System.Type, System.String)
   at EPiServer.Shell.ObjectEditing.MetadataHandlerRegistry.GetMetadataHandlers(System.Type, System.String)
   at EPiServer.Shell.ObjectEditing.ExtensibleMetadataProvider.GetExtendedMetadata(System.Collections.Generic.IEnumerable`1<System.Attribute>, System.Type, System.Func`1<System.Object>, System.Type, System.String)
   at EPiServer.Shell.ObjectEditing.ExtendedMetadata.<get_Properties>b__37_0(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata)
   at System.Linq.Enumerable+SelectIListIterator`2[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ToArray()
   at EPiServer.Shell.ObjectEditing.ExtendedMetadata.get_Properties()
   at EPiServer.Shell.UI.Rest.DefaultMetadataStoreModelCreator.ExtractMetadataFromProperties(EPiServer.Shell.ObjectEditing.ExtendedMetadata, EPiServer.Shell.UI.Models.MetadataStoreModel, EPiServer.Framework.Localization.LocalizationService, EPiServer.Shell.UIDescriptorRegistry, EPiServer.Shell.ObjectEditing.ISelectionFactory[])
   at EPiServer.Shell.UI.Rest.DefaultMetadataStoreModelCreator.CreateFromModelMetadata(EPiServer.Shell.ObjectEditing.ExtendedMetadata, EPiServer.Framework.Localization.LocalizationService, EPiServer.Shell.UIDescriptorRegistry, EPiServer.Shell.ObjectEditing.ISelectionFactory[], Boolean)
   at EPiServer.Shell.UI.Rest.DefaultMetadataStoreModelCreator.ExtractMetadataFromProperties(EPiServer.Shell.ObjectEditing.ExtendedMetadata, EPiServer.Shell.UI.Models.MetadataStoreModel, EPiServer.Framework.Localization.LocalizationService, EPiServer.Shell.UIDescriptorRegistry, EPiServer.Shell.ObjectEditing.ISelectionFactory[])
   at EPiServer.Shell.UI.Rest.DefaultMetadataStoreModelCreator.CreateFromModelMetadata(EPiServer.Shell.ObjectEditing.ExtendedMetadata, EPiServer.Framework.Localization.LocalizationService, EPiServer.Shell.UIDescriptorRegistry, EPiServer.Shell.ObjectEditing.ISelectionFactory[], Boolean)
   at EPiServer.Shell.UI.Rest.DefaultMetadataStoreModelCreator.ExtractMetadataFromProperties(EPiServer.Shell.ObjectEditing.ExtendedMetadata, EPiServer.Shell.UI.Models.MetadataStoreModel, EPiServer.Framework.Localization.LocalizationService, EPiServer.Shell.UIDescriptorRegistry, EPiServer.Shell.ObjectEditing.ISelectionFactory[])
   at EPiServer.Shell.UI.Rest.DefaultMetadataStoreModelCreator.CreateFromModelMetadata(EPiServer.Shell.ObjectEditing.ExtendedMetadata, EPiServer.Framework.Localization.LocalizationService, EPiServer.Shell.UIDescriptorRegistry, EPiServer.Shell.ObjectEditing.ISelectionFactory[], Boolean)
   at EPiServer.Shell.UI.Rest.DefaultMetadataStoreModelCreator.ExtractMetadataFromProperties(EPiServer.Shell.ObjectEditing.ExtendedMetadata, EPiServer.Shell.UI.Models.MetadataStoreModel, EPiServer.Framework.Localization.LocalizationService, EPiServer.Shell.UIDescriptorRegistry, EPiServer.Shell.ObjectEditing.ISelectionFactory[])
   at EPiServer.Shell.UI.Rest.DefaultMetadataStoreModelCreator.CreateFromModelMetadata(EPiServer.Shell.ObjectEditing.ExtendedMetadata, EPiServer.Framework.Localization.LocalizationService, EPiServer.Shell.UIDescriptorRegistry, EPiServer.Shell.ObjectEditing.ISelectionFactory[], Boolean)
#307463
Aug 25, 2023 11:05
Vote:
 

I would remove [EditorDescriptor(EditorDescriptorType = typeof(CollectionEditorDescriptor<ExampleListItem>))] and have ExampleListItem inherit from block data.  I think the issues is you mising new inline blocks and old property list

#307466
Aug 25, 2023 21:20
Ted
Vote:
 

Hi Mark! We have a lot of block types with IList<T> properties where T is a POCO type.

We're not using IList<T> where T is a block type in this case, so I don't think we're mixing the two (let me know if I misunderstood what you meant).

This exact setup works if the Link property is, for example, of type ContentReference.

So I think this should work, but there seems to be a bug related to serialization?

Or is Optimizely officially removing the support for POCO types, forcing all IList item types (except value types) to in fact be block types going forward?

#307577
Edited, Aug 28, 2023 8:22
Vote:
 

Not answering the question directly, but maybe you can be interested in Geta Generic Links - they try to solve need similar to what you/ve described https://www.getadigital.com/no/blogg/extending-link-item-collections

There can be some issues with Content Management API though (thats how I stumbled on that package) so be warned.

#307578
Aug 28, 2023 12:15
* 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.