Allan Thraen
OMVPCommerce Connect 14 Developer CertificationOpal Tools Certification +1
Nov 27, 2017
visibility 7919
star star star star star
(2 votes)

Limit number of elements in a LinkItemCollection or ContentArea

A colleague asked me today how to ensure that editors don't add too many elements in a LinkItemCollection or ContentArea - since too many could potentially break the design. I figured a simple validation attribute could do the trick - and sure enough, it can. I figured I'd share it here as it's a nice example of how to do custom validations of property values. I could have extended it even further to also ensure that the front-end code wouldn't even allow for the editor to try and drop an element if there's already too many - but due to time restraints and my limited dojo-skills, I simply left that part as a fun TODO for all of you out there. If you have that part, feel free to share in the comments...

Here is the main class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.ModelBinding;
using EPiServer.Core;
using EPiServer.ServiceLocation;
using EPiServer.Shell.ObjectEditing;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using EPiServer.SpecializedProperties;

namespace ExperimentsValidationAttributes
{
    /// <summary>
    /// Sets the maximum element count in a linkcollection, a content area - or any other type of collection.
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class MaxElementsAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute, IMetadataAware
    {
        public int MaxCount { get; set; }

        public void OnMetadataCreated(ModelMetadata metadata)
        {
            //TODO: Use to disable editor drag and drop at a certain point.
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value == null)
            {
                return null;
            }
            if(value is LinkItemCollection)
            {
                if((value as LinkItemCollection).Count > MaxCount)
                {
                    return new ValidationResult("Too many Link Items in the collection. Maximum is " + MaxCount);
                }
            } else if(value is ContentArea)
            {
                if((value as ContentArea).Count>MaxCount)
                {
                    return new ValidationResult("Too many content items in content area. Maximum is " + MaxCount);
                }
            } 

            return null;
        }

        public MaxElementsAttribute(int MaxElementsInList)
        {
            this.MaxCount = MaxElementsInList;
        }
    }
}

And of course it's straightforward to use:

        [MaxElements(3)]
        public virtual LinkItemCollection Links { get; set; }

        [Display(
            GroupName = SystemTabNames.Content,
            Order = 320)]
        [MaxElements(5)]
        public virtual ContentArea MainContentArea { get; set; }
Nov 27, 2017

Comments

valdis
valdis Nov 28, 2017 10:16 AM

cool. also, similar - if you are using Bootstrap and want to notify editors that too much items in that content area might blow up something - you can use very similar validator. https://github.com/valdisiljuconoks/EPiBootstrapArea/blob/master/README.md#validate-item-count

Robert Runge
Robert Runge Nov 29, 2017 10:05 AM

Nice. Does this take into consideration the use of visitor groups?

I might want maximum five elements per visitor group - and not in all.

error Please login to comment.
Latest blogs
Surviving a Dirty Feed. Part 3: Error Handling and Event Batching

Committing a 250,000-row Optimizely catalog import row by row, returning a per-row failure report, and coalescing catalog events into one per batch.

Stanisław Szołkowski | Oct 16, 2026 |

Building UI Extensions for Optimizely SaaS CMS

Introduction Developers have been extending the functionality of Optimizely PaaS CMS for years using addons built in C# and deployed as NuGet...

Mark Stott | Oct 15, 2026

Cheapskate AI Translator: Because Translation Should Not Require a Second Mortgage

There is a particular kind of software project that begins with a detailed architecture document, a product roadmap, and a carefully assembled...

Linh Doan Cuu | Oct 15, 2026

Computed Fields in CMS 13 Content Contracts with Optimizely Graph

Content Contracts in Optimizely CMS 13 allow different content types to share a common structure when querying Optimizely Graph. But what if the...

Mardy | Oct 14, 2026