Giter Club home page Giter Club logo

geta-optimizely-genericlinks's People

Contributors

svenrog avatar valdisiljuconoks avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

geta-optimizely-genericlinks's Issues

Content Creation Screen is blank when a custom link is present

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; }
    }

image

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.

Display and functionality issues in quick edit

Hello,

When a block has a generic link property, the display is not working correctly in the quick edit dialog.

image

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.

System.InvalidCastException: Unable to cast object of type 'EPiServer.SpecializedProperties.LinkItemCollection' to type 'Geta.Optimizely.GenericLinks.LinkDataCollection`1[Geta.Optimizely.Web.Infrastructure.Cms.IconLinkData]'

while creating block containing LinkDataCollection

image

System.InvalidCastException: Unable to cast object of type 'EPiServer.SpecializedProperties.LinkItemCollection' to type 'Geta.Optimizely.GenericLinks.LinkDataCollection1[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, List1 validationResult, ValidationContext validationContext)
at EPiServer.Validation.DataAnnotationsValidator1.Validate(T instance) at EPiServer.Validation.Internal.ContextValidatorWrapper2.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, Nullable1 resourceFolderId, Boolean createAsLocalAsset, String name, IDictionary2 properties, SaveAction saveAction) at EPiServer.Cms.Shell.UI.Rest.ContentChangeManager.CreateContent(ContentReference parentLink, Int32 contentTypeId, Nullable1 resourceFolderId, Boolean createAsLocalAsset, String name, IDictionary2 properties, Boolean autoPublish) at EPiServer.Cms.Shell.UI.Rest.ContentChangeManager.Create(ContentReference parentLink, Int32 contentTypeId, Nullable1 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)

`

'Compare different versions' option doesn't work when adding an external link to a page

How to reproduce:

  • Define Optimizely page and add a LinkDataCollection as described here
  • Run the application, create page and add an external link to the page
  • Try to compare versions

image

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)"

Can't Add Validation to Existing String Properties

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.

Properties not coming out in ContentApi calls

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

LinkData is not copied when using 'Duplicate Content' from Language gadget

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.
image

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.

Set default value to property

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).

Language field is not used in LinkData

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.

image

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?

Autosave on cancel clears link property

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

Link text disappearing from attribute dictionary on value change

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.

Custom boolean value resets when published

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!

Select content modal is empty

With the latest version of Umbraco CMS 12.22.1 when you are using a LinkDataCollection, if you choose to "Select Content" rather than "Create a new link" then the modal that appears is showing as empty and no tree-view is showing. This has been tested on a fresh install of the Alloy demo site.

image

Add projectUrl to Nuget package

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"

LinkDataBackingTypeResolverInterceptor May Throw Exception During Startup

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.

image

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()

Delete button does not trigger autosave, or remove link

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.

delete-link-1
delete-link-2

Thank you,
Joe Mayberry

GenericLinks (v1.8.0) crashes Admin UI after updating EPiServer.CMS.UI (v12.24.0)

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.
image

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)'

Deserialisation of LinkDataCollection in Optimizely v12 ContentManagement API

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

Property value reset on publish

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

GetAttribute throws exception when passing Enum.Parse<Type>

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?

Error when adding property values in "create mode"

How to reproduce

  • Create new block
  • Fill inn values for heading and add links
  • Press 'Create'

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.LinkDataCollection1[Skeidar.Web.Infrastructure.Properties.ThumbnailLinkData]'. Path: $[0] | LineNumber: 0 | BytePositionInLine: 2. ---> System.NotSupportedException: Specified method is not supported. at Geta.Optimizely.GenericLinks.Converters.Json.SystemTextLinkDataConverter1.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.IEnumerableDefaultConverter2.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.JsonConverter1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.