geta / geta-optimizely-genericlinks Goto Github PK
View Code? Open in Web Editor NEWAn extensive alternative to LinkItemCollection in Optimizely.
License: Apache License 2.0
An extensive alternative to LinkItemCollection in Optimizely.
License: Apache License 2.0
Hello,
I am running into an issue - I have created a custom LinkData property and I am using it on our models. There is an issue at the moment that if there is a custom LinkData present then no properties will show on the content creation screen in the CMS.
public class GeneralLinkData : LinkData
{
[ScaffoldColumn(false)]
public override string? Target => OpenInNewTab ? "_blank" : "_self";
[ScaffoldColumn(false)]
public override string? Title => base.Text;
[Ignore]
public Url? Url => !string.IsNullOrWhiteSpace(base.Href) ? new Url(base.Href) : null;
[Display(Name = "Open In New Tab")]
public virtual bool OpenInNewTab
{
get => GetAttribute((v) => bool.Parse(v));
set => SetAttribute(value, (v) => v.ToString());
}
[Required]
public override string? Href
{
get => base.Href;
set => base.Href = value;
}
}
[PropertyDefinitionTypePlugIn(
DisplayName = "General link",
GUID = "41589b68-f826-459e-bc11-e4db2c8f51cc")]
public class PropertyGeneralLink : PropertyLinkData<GeneralLinkData>
{
}
[ContentType(
DisplayName = "Static Three Up Item",
Description = "An item to be used in a Static Three Up block.",
GUID = "eec5gfea-f570-4384-8916-ec2279a0cc80")]
[ImageUrl("~/assets/images/episerver/thumbnails/staticthreeupitemblock.png")]
public class StaticThreeUpItemBlock : BlockData
{
[Required]
public virtual string? Heading { get; set; }
[Required]
public virtual GeneralLinkData? Link { get; set; }
[UIHint(UIHint.Image)]
public virtual ContentReference? Image { get; set; }
public virtual string? Text { get; set; }
}
As you can see from the screenshot, when I have the custom LinkData property on the model, the creation screen is completely blank. If I set it to [ScaffoldColumn(false)] the properties will show again.
This is a showstopper as when you create block directly from a ContentArea, it will not let you create it without required fields being populated, so the item cannot be added this way.
Hello,
When a block has a generic link property, the display is not working correctly in the quick edit dialog.
I think this just needs the main box having a width of calc(100% - 42px)
.
Functionality:
It seems that the link is added correctly, but when clicking the 3 dots to edit again, the data is missing.
while creating block containing LinkDataCollection
System.InvalidCastException: Unable to cast object of type 'EPiServer.SpecializedProperties.LinkItemCollection' to type 'Geta.Optimizely.GenericLinks.LinkDataCollection
1[Geta.Optimizely.Web.Infrastructure.Cms.IconLinkData]'.
at Castle.Proxies.LinkListBlockProxy.get_Links()
at lambda_method861(Closure , Object , Object[] )
at EPiServer.Validation.DataAnnotationsValidator1.ValidateInstance(Object instance, List
1 validationResult, ValidationContext validationContext)
at EPiServer.Validation.DataAnnotationsValidator1.Validate(T instance) at EPiServer.Validation.Internal.ContextValidatorWrapper
2.Validate(Object instance, Object context)
at EPiServer.Validation.Internal.ValidationService.ValidateRecursively(Object instance, Object context, HashSet1 visitedInstances) at EPiServer.Validation.Internal.ValidationService.Validate[T](Object instance, T context) at EPiServer.Core.ContentProvider.Validate(IContent content, ContentSaveValidationContext saveValidationContext) at EPiServer.Core.Internal.DefaultContentRepository.Save(IContent content, SaveAction action, AccessLevel access) at EPiServer.Cms.Shell.Service.Internal.ContentService.Save(IContent content, SaveAction saveAction, AccessLevel accessLevel) at EPiServer.Cms.Shell.Service.Internal.ContentService.Save(IContent content, SaveAction saveAction) at EPiServer.Cms.Shell.UI.Rest.ContentChangeManager.CreateContent(ContentReference parentLink, Int32 contentTypeId, Nullable
1 resourceFolderId, Boolean createAsLocalAsset, String name, IDictionary2 properties, SaveAction saveAction) at EPiServer.Cms.Shell.UI.Rest.ContentChangeManager.CreateContent(ContentReference parentLink, Int32 contentTypeId, Nullable
1 resourceFolderId, Boolean createAsLocalAsset, String name, IDictionary2 properties, Boolean autoPublish) at EPiServer.Cms.Shell.UI.Rest.ContentChangeManager.Create(ContentReference parentLink, Int32 contentTypeId, Nullable
1 resourceFolderId, Boolean createAsLocalAsset, String name, IDictionary`2 properties, Boolean autoPublish)
at EPiServer.Cms.Shell.UI.Rest.Internal.ContentDataStore.Post(PostContentModel entity)
at lambda_method849(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Geta.Optimizely.Domain.Infrastructure.DynamicRendering.DynamicRendererMiddleware.InvokeAsync(HttpContext context) in C:\projects\site\src\Geta.Domain\Infrastructure\DynamicRendering\DynamicRenderingMiddleware.cs:line 41
at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
at Mediachase.Commerce.Anonymous.Internal.AnonymousIdMiddleware.Invoke(HttpContext httpContext)
at SixLabors.ImageSharp.Web.Middleware.ImageSharpMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
`
How to reproduce:
I got "Preview is not available for this item" on the screen and this error in dev console:
epi.js:4092 TypeError: Cannot read properties of null (reading 'map')
at Object._valueGetter (ItemCollectionViewModel.js:237:25)
at Object._get (epi.js:4422:71)
at Object.get (epi.js:4440:25)
at Object._getValueAttr (ItemCollectionEditor.js:533:31)
at Object.get (_WidgetBase.js:746:39)
at _FormMixin.js:91:36
at Object.forEach (dojo.js:3612:6)
at Object._getValueAttr (_FormMixin.js:86:19)
at Object.get (_WidgetBase.js:746:39)
at Object._getValueAttr (FormContainer.js:114:50) "TypeError: Cannot read properties of null (reading 'map')\n at Object._valueGetter (https://paragon.localtest.me:8443/EPiServer/Geta.Optimizely.GenericLinks/1.5.0/viewmodel/ItemCollectionViewModel.js:237:25)\n at Object._get (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/epi/epi.js:4422:71)\n at Object.get (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/epi/epi.js:4440:25)\n at Object._getValueAttr (https://paragon.localtest.me:8443/EPiServer/CMS/12.22.1/ClientResources/epi-cms/contentediting/editors/ItemCollectionEditor.js:533:31)\n at Object.get (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dijit/_WidgetBase.js:746:39)\n at https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/EPi/patch/dijit/form/_FormMixin.js:91:36\n at Object.forEach (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:3612:6)\n at Object._getValueAttr (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/EPi/patch/dijit/form/_FormMixin.js:86:19)\n at Object.get (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dijit/_WidgetBase.js:746:39)\n at Object._getValueAttr (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/EPi/shell/widget/FormContainer.js:114:50)\n ----------------------------------------\n rejected at signalDeferred (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:8372:15)\n at signalListener (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:8343:5)\n at Deferred.then.promise.then (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:8546:5)\n at when (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:9065:26)\n at Object.<anonymous> (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/EPi/shell/widget/FormContainer.js:278:25)\n at https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:3135:55\n at runFactory (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:1107:43)\n at execModule (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:1236:5)\n at https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:802:7\n at guardCheckComplete (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:1251:5)\n ----------------------------------------\nError\n at Deferred.then.promise.then (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:8540:24)\n at when (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:9065:26)\n at Object.<anonymous> (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/EPi/shell/widget/FormContainer.js:278:25)\n at https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:3135:55\n at runFactory (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:1107:43)\n at execModule (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:1236:5)\n at https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:802:7\n at guardCheckComplete (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:1251:5)\n at contextRequire (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:801:6)\n at req (https://paragon.localtest.me:8443/EPiServer/Shell/12.22.1/ClientResources/dojo/dojo.js:137:11)"
Firstly, this is really helpful and maybe should be a native CMS feature, but it seems lack the validation on Text and Link properties which the native LinkItemCollection
. So, I was able to get the Required
attribute to work on the Link property, but that override didn't work of the Text property.
seems these properties are not included in the ContentApi responses by default.
do I need to create a PropertyModel<??, ??> and Converter for each of them?
not sure of the most useful backing type to use
When LinkData (in our case a sub-class of LinkData) is used in content and respective property is culture-specific, duplicating content from Language gadget does not respect LinkData property.
After new content (block/page) is created (from duplication context menu), LinkData property is empty.
Property:
[CultureSpecific] public virtual ExtendedLinkData? Link { get; set; }
public class ExtendedLinkData : LinkData ...
This happens with Versions 1.8.1 and 1.8.2
UPDATE:
Language variants are created with LanguageBranchManager in method CopyDataForNestedContentRecursive where the value of property (of type LinkData) is assigned to property of duplicated/cloned content using PropertyData instances.
This assignment is directly assigning to private field _linkData of class Geta.Optimizely.GenericLinks.PropertyLinkData. As source property value is not modified, destination value will neither be in modified state.
When I override Value property in our code (PropertyExtendedLink : PropertyLinkData) and assign value in this way
if (value is ExtendedLinkData linkData2) { Link = linkData2; } else { base.Value = value; }
which implicitly sets IsModified to true, the language variant will have set the correct LinkData value.
Hi
We use GenericLinks for all LinkItem properties in our project. However when we ran the import/export tool, any links pointing to CMS Pages, did not get imported correctly. Please review and let us know if/when this integration will be fixed.
Is there a way to set a default value for a property on a link data model in a LinkDataCollection?
For example, I have a string property in the linkdatamodel that needs to be set for each item with a unique value (in this case a guid).
I'm trying to use the LinkData type to create multilingual links. I can see that there is a language dropdown which is populated by the enabled languages in the CMS.
However, I can't find a way to get the value of this field in the code so I can apply it to the URL. It also doesn't appear to do anything to the Href field.
Do you know how this field value can be obtained or if not, how can I hide it and add a custom one?
We are currently running GenericLinks version 1.4.5 with Optimizely CMS version 12.19.0.
We are seeing an issue where editing an existing link, clicking Cancel, will trigger a CMS autosave. If the content is then published, the generic link property will be cleared and all link data lost.
I noticed in the Changelog there is a version 1.5.0 for generic links, but the NuGet feed does only goes to version 1.4.5.
Is this issue addressed in 1.5.0? and if so, when will it be available from NuGet.
Thank you,
Joe Mayberry
Hi
I'm noticing that the link text value gets stored into the attribute dictionary the first time its added. But when we modify its value subsequently, it disappears from the attribute dictionary. We have some validation applied to the Link text and title fields, that we are applying by looking at the attribute collection. But because of this behavior, its only getting applied to the title and never the text.
Please review and provide feedback.
When there is a LinkDataCollection inside a property list, the property list stops responding correctly - images cannot be dragged from the media gallery and updates stop being saved to the database.
Optimizely CMS 12.19.0
Optimizely CMS UI 12.23.0
This issue was previously mentioned in #10 but was closed by the author without commenting. I'm hoping I just need advice on this one.
We have a custom field used to simplify the setting of a URL target:
[Display(Name = "Open In New Tab")]
public virtual bool OpenInNewTab
{
get => GetAttribute((v) => bool.Parse(v));
set => SetAttribute(value, (v) => v.ToString());
}
However, this property appears to reset to it's unchecked state after the block/page has been published.
See demo:
screen-capture.webm
Please let me know if the code above is wrong or if this is a genuine bug.
Cheers!
The current package has a link to the repository using the <repository>
tag in the nuspec file, which is not shown on the Optimizely Nuget package page.
If you add the url to the repo in the <projectUrl>
as well, the package page will link to the "Project Site"
Geta-Optimmizely-GenericLinks Version: 1.8.1
Optimizely Version: 12.24.0
The exception below is caused by that LinkDataBackingTypeResolverInterceptor.TryResolveType
can be called multiple times in parallel. The method does only validate if a type is in the dictionary at the beginning and later calls the Add method on the dictionary if it was resolved, it can result in an exception being thrown if another thread has already resolved and added the type.
I suggest changing to calling TryAdd
on the dictionary or using some kind of locking.
Screenshot from just before the exception:
You can see in the IEnumerableVisualizer that two types is present in the dictionary and in the Watch window you can see that a duplicate value is about to be added.
Logged Exception:
[ERR] Initialize action failed for 'Initialize on class EPiServer.Initialization.Internal.ModelSyncInitialization, EPiServer, Version=12.19.0.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7'
System.AggregateException: One or more errors occurred. (An item with the same key has already been added. Key: XXXXXXX.Features.Linkdata.Models.IconLinkBase)
---> System.ArgumentException: An item with the same key has already been added. Key: XXXXXXX.Features.Linkdata.Models.IconLinkBase
at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at Geta.Optimizely.GenericLinks.Cms.Registration.LinkDataBackingTypeResolverInterceptor.TryResolveType(Type type, Type baseType)
at Geta.Optimizely.GenericLinks.Cms.Registration.LinkDataBackingTypeResolverInterceptor.Resolve(Type type)
at EPiServer.DataAbstraction.RuntimeModel.Internal.PropertyDefinitionSynchronizer.ResolveType(PropertyDefinitionModel model)
at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelRegister.ValidateChangeOfModelType(PropertyDefinitionModel propertyModel, String modelName)
at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelRegister.SetStateForPropertyDefinitionModels(ContentTypeModel model)
at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelRegister.<AnalyzeProperties>b__15_0(ContentTypeModel model)
at System.Threading.Tasks.Parallel.<>c__DisplayClass33_0`2.<ForEachWorker>b__0(Int32 i)
at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.<ForWorker>b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
--- End of stack trace from previous location ---
at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.<ForWorker>b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
at System.Threading.Tasks.TaskReplicator.Replica.Execute()
--- End of inner exception stack trace ---
at System.Threading.Tasks.TaskReplicator.Run[TState](ReplicatableUserAction`1 action, ParallelOptions options, Boolean stopOnFirstFailure)
at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
--- End of stack trace from previous location ---
at System.Threading.Tasks.Parallel.ThrowSingleCancellationExceptionOrOtherException(ICollection exceptions, CancellationToken cancelToken, Exception otherException)
at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IList`1 list, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IEnumerable`1 source, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.ForEach[TSource](IEnumerable`1 source, Action`1 body)
at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelRegister.AnalyzeProperties()
at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelScanner.Sync(Boolean forceCommit)
at EPiServer.Initialization.Internal.ModelSyncInitialization.Initialize(InitializationEngine context)
at EPiServer.Framework.Initialization.Internal.ModuleNode.Execute(Action a, String key)
at EPiServer.Framework.Initialization.Internal.ModuleNode.Initialize(InitializationEngine context)
at EPiServer.Framework.Initialization.InitializationEngine.InitializeModules()
We are currently running GenericLinks version 1.6.1 with Optimizely CMS version 12.19.0.
We are seeing an issue where clicking the delete button, either the "DELETE" button on the link properties modal or the 'X' button content reference link, does not trigger an autosave, and does not remove the link.
Thank you,
Joe Mayberry
I'd like to be able to have a genericlink as a property of a genericlink in order to create hierarchies for navigation. Do you have any suggestions... I notice that the Property Types links https://github.com/Geta/geta-optimizely-genericlinks/blob/master/docs/advanced-property-handling.md#supported-property-types explicitly excludes blocks...
What is the problem
After package update to the latest versions, Optimizely Admin UI fails to load if page contains a property of type LinkDataCollection<T>
.
The UI completely locks up - not even page name gets displayed.
Changes to any properties are not detected. It is not possible to (simply) roll back package update as Optimizely data migrations have been performed.
What have we tried
Adding [ScaffoldColumn(false)]
on properties of type LinkDataCollection<T>
makes UI responsive again. Which suggests that the package is causing this.
What is the setup / versions used
<PackageReference Include="Geta.Optimizely.GenericLinks" Version="1.8.0" />
<PackageReference Include="EPiServer.CloudPlatform.Cms" Version="1.4.0" />
<PackageReference Include="EPiServer.CloudPlatform.Commerce" Version="1.1.2" />
<PackageReference Include="EPiServer.CMS" Version="12.24.0" />
<PackageReference Include="EPiServer.CMS.AspNetCore.HtmlHelpers" Version="12.19.1" />
<PackageReference Include="EPiServer.CMS.AspNetCore.Mvc" Version="12.19.1" />
<PackageReference Include="EPiServer.CMS.AspNetCore.Routing" Version="12.19.1" />
<PackageReference Include="EPiServer.CMS.AspNetCore.Templating" Version="12.19.1" />
<PackageReference Include="EPiServer.CMS.Core" Version="12.19.1" />
<PackageReference Include="EPiServer.CMS.UI" Version="12.24.0" />
<PackageReference Include="EPiServer.CMS.UI.Core" Version="12.24.0" />
<PackageReference Include="EPiServer.Commerce" Version="14.15.3" />
<PackageReference Include="EPiServer.Find.Commerce" Version="12.1.3" />
<PackageReference Include="EPiServer.Framework" Version="12.19.1" />
<PackageReference Include="EPiServer.Hosting" Version="12.19.1" />
<PackageReference Include="EPiServer.Labs.LanguageManager" Version="5.2.0" />
<PackageReference Include="EPiServer.OpenIDConnect.UI" Version="3.9.1" />
<PackageReference Include="EPiServer.ServiceApi.Commerce" Version="7.0.2" />
What is the actual error
There is an error displayed in browser console:
epi.js:4093 TypeError: this.model.hasReachedItemsLimit is not a function
at Object._renderUI (ItemCollectionEditor.js:621:47)
at Object.dispatcher [as oninitCompleted] (dojo.js:6145:59)
at on.emit (dojo.js:5719:37)
at on.emit (dojo.js:5761:29)
at Object.emit (dojo.js:6040:19)
at Object.inherited__debug [as inherited] (dojo.js:4194:19)
at Object.emit (_ViewModelMixin.js:48:18)
at ItemCollectionViewModel.js:173:16
at signalListener (dojo.js:8325:21)
at Deferred.then.promise.then (dojo.js:8546:5) 'TypeError: this.model.hasReachedItemsLimit is not a function\n at Object._renderUI (https://masked.localtest.me:8443/EPiServer/CMS/12.24.0/ClientResources/epi-cms/contentediting/editors/ItemCollectionEditor.js:621:47)\n at Object.dispatcher [as oninitCompleted] (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:6145:59)\n at on.emit (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:5719:37)\n at on.emit (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:5761:29)\n at Object.emit (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:6040:19)\n at Object.inherited__debug [as inherited] (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:4194:19)\n at Object.emit (https://masked.localtest.me:8443/EPiServer/CMS/12.24.0/ClientResources/epi-cms/contentediting/viewmodel/_ViewModelMixin.js:48:18)\n at https://masked.localtest.me:8443/EPiServer/Geta.Optimizely.GenericLinks/1.8.0/viewmodel/ItemCollectionViewModel.js:173:16\n at signalListener (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:8325:21)\n at Deferred.then.promise.then (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:8546:5)\n ----------------------------------------\n rejected at signalDeferred (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:8372:15)\n at signalListener (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:8343:5)\n at Deferred.then.promise.then (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:8546:5)\n at Object._init (https://masked.localtest.me:8443/EPiServer/Geta.Optimizely.GenericLinks/1.8.0/viewmodel/ItemCollectionViewModel.js:171:23)\n at Object._dataSetter (https://masked.localtest.me:8443/EPiServer/Geta.Optimizely.GenericLinks/1.8.0/viewmodel/ItemCollectionViewModel.js:247:12)\n at Object.set (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/epi/epi.js:4485:33)\n at Object._setValueAttr (https://masked.localtest.me:8443/EPiServer/CMS/12.24.0/ClientResources/epi-cms/contentediting/editors/ItemCollectionEditor.js:552:41)\n at Object.set (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dijit/_WidgetBase.js:785:24)\n at Object.setEditorValue (https://masked.localtest.me:8443/EPiServer/CMS/12.24.0/ClientResources/epi-cms/contentediting/_EditorWrapperBase.js:359:20)\n at Object.inherited__debug [as inherited] (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:4194:19)\n ----------------------------------------\nError\n at Deferred.then.promise.then (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:8540:24)\n at Object._init (https://masked.localtest.me:8443/EPiServer/Geta.Optimizely.GenericLinks/1.8.0/viewmodel/ItemCollectionViewModel.js:171:23)\n at Object._dataSetter (https://masked.localtest.me:8443/EPiServer/Geta.Optimizely.GenericLinks/1.8.0/viewmodel/ItemCollectionViewModel.js:247:12)\n at Object.set (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/epi/epi.js:4485:33)\n at Object._setValueAttr (https://masked.localtest.me:8443/EPiServer/CMS/12.24.0/ClientResources/epi-cms/contentediting/editors/ItemCollectionEditor.js:552:41)\n at Object.set (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dijit/_WidgetBase.js:785:24)\n at Object.setEditorValue (https://masked.localtest.me:8443/EPiServer/CMS/12.24.0/ClientResources/epi-cms/contentediting/_EditorWrapperBase.js:359:20)\n at Object.inherited__debug [as inherited] (https://masked.localtest.me:8443/EPiServer/Shell/12.24.0/ClientResources/dojo/dojo.js:4194:19)\n at Object.setEditorValue (https://masked.localtest.me:8443/EPiServer/CMS/12.24.0/ClientResources/epi-cms/contentediting/SideBySideEditorWrapper.js:108:18)\n at Object._setValueAttr (https://masked.localtest.me:8443/EPiServer/CMS/12.24.0/ClientResources/epi-cms/contentediting/_EditorWrapperBase.js:364:18)'
Hello,
I'm an Optimizely newbie, so apologies if this is a silly question.
I'm creating items in Optimizely v12 via the Content Management API.
I've got a property of type LinkDataCollection<GeneralLinkData>
which all works fine in the CMS and via GET requests to the Content Management API.
Retrieving a Block with this property contains the following JSON:
"links": {
"value": [
{
"target": "_self",
"title": "Test Link 1",
"url": {
"originalString": "https://www.google.co.uk",
"path": "/",
"authority": "www.google.co.uk",
"dnsSafeHost": "www.google.co.uk",
"fragment": "",
"host": "www.google.co.uk",
"isAbsoluteUri": true,
"localPath": "/",
"pathAndQuery": "/",
"port": 443,
"query": "",
"queryCollection": [],
"scheme": "https",
"segments": [
"/"
],
"userEscaped": false,
"userInfo": "",
"uri": "https://www.google.co.uk",
"encoding": {
"bodyName": "utf-8",
"encodingName": "Unicode (UTF-8)",
"headerName": "utf-8",
"webName": "utf-8",
"windowsCodePage": 1200,
"isBrowserDisplay": true,
"isBrowserSave": true,
"isMailNewsDisplay": true,
"isMailNewsSave": true,
"isSingleByte": false,
"encoderFallback": {
"defaultString": "�",
"maxCharCount": 1
},
"decoderFallback": {
"defaultString": "�",
"maxCharCount": 1
},
"isReadOnly": true,
"codePage": 65001
}
},
"openInNewTab": false,
"href": "https://www.google.co.uk",
"text": "Test Link 1",
"attributes": {
"openInNewTab": "false",
"href": "https://www.google.co.uk"
}
},
{
"target": "_self",
"title": "Test Link 2",
"url": {
"originalString": "https://www.google.co.uk",
"path": "/",
"authority": "www.google.co.uk",
"dnsSafeHost": "www.google.co.uk",
"fragment": "",
"host": "www.google.co.uk",
"isAbsoluteUri": true,
"localPath": "/",
"pathAndQuery": "/",
"port": 443,
"query": "",
"queryCollection": [],
"scheme": "https",
"segments": [
"/"
],
"userEscaped": false,
"userInfo": "",
"uri": "https://www.google.co.uk",
"encoding": {
"bodyName": "utf-8",
"encodingName": "Unicode (UTF-8)",
"headerName": "utf-8",
"webName": "utf-8",
"windowsCodePage": 1200,
"isBrowserDisplay": true,
"isBrowserSave": true,
"isMailNewsDisplay": true,
"isMailNewsSave": true,
"isSingleByte": false,
"encoderFallback": {
"defaultString": "�",
"maxCharCount": 1
},
"decoderFallback": {
"defaultString": "�",
"maxCharCount": 1
},
"isReadOnly": true,
"codePage": 65001
}
},
"openInNewTab": false,
"href": "https://www.google.co.uk",
"text": "Test Link 2",
"attributes": {
"openInNewTab": "false",
"href": "https://www.google.co.uk"
}
}
],
"propertyDataType": "GeneralLinkCollection"
}
However, if I try to create a new Block using exactly the same JSON, I get the following error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Geta.Optimizely.GenericLinks.LinkDataCollection' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.\r\nPath 'value'.
Is there a step I'm missing to allow this object to be deserialised via the Content Management API?
I see there's a separate package for performing conversions for the Content Delivery API (referenced in #6) but not sure if this will solve my problems in the Content Management API and thought I'd ask before throwing myself down a(nother!) rabbit hole.
Any help would be greatly appreciated.
Thanks,
Antony
I have extended LinkData to with this fileds
[Display(Name = "Thumbnail image", Order = 0)]
[AllowedTypes(AllowedTypes = new[] { typeof(ImageFile) })]
[UIHint(UIHint.Image)]
public virtual ContentReference? ThumbnailImage
{
get => GetAttribute((v) => ContentReference.Parse(v));
set => SetAttribute(value, (v) => v.ToString());
}
[Display(Name = "Hide image", Order = 10)]
public virtual bool HideImage
{
get => GetAttribute(v => bool.Parse(v));
set => SetAttribute(value, (v) => v.ToString());
}
If I add link and check on 'Hide image' property and publish updates when I open link to quick edit or edit 'Hide image' is not checked. I'm using version 1.4.1 and Optimizely version 12.6.0
After updating to v 1.6.1, I got an exception in the custom LinkData model, the previous version was ok with that.
Custom LinkData model:
public class ButtonLinkData : LinkData
{
[Display(Name = "Font Awesome Icon", Order = 1)]
[FontAwesomeIcon]
public virtual string? Icon
{
get => GetAttribute(v => v);
set => SetAttribute(value, v => v);
}
[Display(Name = "Icon alignment", Order = 2)]
[LocalizedSelectOneEnum(typeof(IconAlign))]
public virtual IconAlign IconAlign
{
get => GetAttribute(Enum.Parse<IconAlign>);
set => SetAttribute(value, v => v.ToString());
}
[Display(Name = "Button action", Order = 250)]
[LocalizedSelectOneEnum(typeof(ButtonAction))]
[ScaffoldColumn(false)] // Hidden until implemented properly. Should we support OpenModal action?
public virtual ButtonAction ButtonAction
{
get => GetAttribute(Enum.Parse<ButtonAction>); << EXCEPTION THROWS HERE
set => SetAttribute(value, v => v.ToString());
}
[Display(Name = "Button style", Order = 260)]
[LocalizedSelectOneEnum(typeof(ButtonStyle))]
public virtual ButtonStyle ButtonStyle
{
get => GetAttribute(Enum.Parse<ButtonStyle>);
set => SetAttribute(value, v => v.ToString());
}
[Display(Name = "Button size", Order = 270)]
[LocalizedSelectOneEnum(typeof(ButtonSize))]
public virtual ButtonSize ButtonSize
{
get => GetAttribute(Enum.Parse<ButtonSize>);
set => SetAttribute(value, v => v.ToString());
}
}
Exception:
An unhandled exception has occurred while executing the request.
System.ArgumentException: Must specify valid information for parsing in the string. (Parameter 'value')
at System.Enum.TryParse[TEnum](ReadOnlySpan`1 value, Boolean ignoreCase, Boolean throwOnFailure, TEnum& result)
at System.Enum.TryParse[TEnum](String value, Boolean ignoreCase, Boolean throwOnFailure, TEnum& result)
at System.Enum.Parse[TEnum](String value, Boolean ignoreCase)
at System.Enum.Parse[TEnum](String value)
at Geta.Optimizely.GenericLinks.LinkData.GetAttribute[T](Func`2 conversion, String key)
at Geta.Phoenix.Repositories.Infrastructure.Cms.ButtonLinkData.get_ButtonAction() in C:\Projects\geta-paragon\sub\geta-phoenix\src\Geta.Phoenix.Repositories\Infrastructure\Cms\ButtonLinkData.cs:line 32
Exception throws on ButtonAction property when calling GetAttribute.
Has something changed on the GetAttribute level? Or should we do some code updates?
Block will fail to be created and the following error can be retrieved from network tab:
System.NotSupportedException: Specified method is not supported. The unsupported member type is located on type 'Geta.Optimizely.GenericLinks.LinkDataCollection
1[Skeidar.Web.Infrastructure.Properties.ThumbnailLinkData]'. Path: $[0] | LineNumber: 0 | BytePositionInLine: 2. ---> System.NotSupportedException: Specified method is not supported. at Geta.Optimizely.GenericLinks.Converters.Json.SystemTextLinkDataConverter
1.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
at System.Text.Json.Serialization.JsonConverter1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value) at System.Text.Json.Serialization.Converters.IEnumerableDefaultConverter
2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
at System.Text.Json.Serialization.JsonConverter1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value) at System.Text.Json.Serialization.JsonConverter
1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.