[Ignore]-property loses value after IIS reset

Vote:
 

I have a Block type that allows nested blocks for structuring block layouts.

[ContentType(DisplayName = "Row Layout Block")]
public class RowLayoutBlock : BlockData
{

    [Display(Name = "Blocks")]
    [AllowedTypes(typeof(IRowLayoutItemBlock))]
    public virtual ContentArea Items { get; set; }

}

IRowLayoutItemBlock contains a flag that tells the front-end that this block should be handled a little bit differently.

public interface IRowLayoutItemBlock : IContentData
{
    bool IsRowLayoutItem { get; set; }
}

I don't want this flag to be visible/editable in the CMS editor and I've added the [Ignore] attribute on the inherited member.

[ContentType(DisplayName = "Image Block")]
public class ImageBlock : BlockData, IRowLayoutItemBlock
{
    [Ignore]
    public virtual bool IsRowLayoutItem { get; set; }
}

To set this flag I've subscribed an event handler on SavingContent and CreatingContent

context.ConfigurationComplete += delegate
{
    var contentEvents = context.StructureMap().GetInstance<IContentEvents>();

    contentEvents.SavingContent += (sender, args) => RowLayoutBlockContentEventListener.SetIsRowLayoutItemOnItems(args);
    contentEvents.CreatingContent += (sender, args) => RowLayoutBlockContentEventListener.SetIsRowLayoutItemOnItems(args);
};
public class RowLayoutBlockContentEventListener
{
    public static void SetIsRowLayoutItemOnItems(ContentEventArgs args)
    {
        if(args.Content is RowLayoutBlock rowLayoutBlock && rowLayoutBlock.Items?.Items != null)
        {
            var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
            foreach (var item in rowLayoutBlock.Items.Items)
            {
                if (contentRepository.TryGet<IRowLayoutItemBlock>(item.ContentLink, out var rowLayoutItem))
                {
                    rowLayoutItem.IsRowLayoutItem = true;
                }
            }
        }
    }
}

This all work perfectly until I do a restart of IIS when all the flags are unset/set to false for some reason.

Is there a better way to do this or am I just missing something?

#219152
Edited, Mar 30, 2020 11:08
Vote:
 

Try the [ScaffoldColumn(false)] or the [Editable(false)] attributes instead.

Avoid using Ignore attribute on blocks or pages. "here be dragons".

Ignored properties are not really stored by Episerver in the background. They use a static class to store them so it will be wiped when IIS reset etc. Using load balancing and this can cause some serious headaches. So stay away from that one.

#219154
Edited, Mar 30, 2020 11:24
Vote:
 

I don't want to use [Editable(false)] because I want it to be hidden not just "disabled".

If I use [ScaffoldColumn(false)] I get an error "NotSupportedException: The property IsRowLayoutItem is read-only" in RowLayoutBlockContentEventListener on rowLayoutItem.IsRowLayoutItem = true

EDIT: Fixed it with a writable clone and a bunch of ugly casts. Seems to work, thanks!

private static void SetIsRowLayoutItemOnItems(ContentEventArgs args)
{
    if(args.Content is RowLayoutBlock rowLayoutBlock && rowLayoutBlock.Items?.Items != null)
    {
        var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
        foreach (var item in rowLayoutBlock.Items.Items)
        {
            if (contentRepository.TryGet<IRowLayoutItemBlock>(item.ContentLink, out var rowLayoutItem))
            {
                var content = (IContent)((IReadOnly)rowLayoutItem).CreateWritableClone();
                ((IRowLayoutItemBlock)content).IsRowLayoutItemBlock = true;
                contentRepository.Save(content, SaveAction.Publish | SaveAction.ForceCurrentVersion, AccessLevel.NoAccess);
            }
        }
    }
}
#219158
Edited, Mar 30, 2020 13:20
Vote:
 

If you want to disable the property, or show is as read-only, you could use this attribute:

[Editable(false)]
#219193
Mar 31, 2020 6:06
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.