How to Create a Custom Content Area Validator in Episerver?

In some projects, you may want to add some form of custom validation in your content areas, for example you may only want to allow 5 blocks in a carousel, or, you only want certain blocks to be allowed.  In Episerver there isn’t a very easy way to do it via the UI, if you even tried it would probably involve dojo.  Instead, you can create a custom validation attribute you can add to a content area to apply your rules.  If the validation fails, the page won’t save and an error message can be displayed back to the user.

using System;
using EPiServer.Core;
namespace Validator
{
[AttributeUsage(AttributeTargets.Property |
AttributeTargets.Field |
AttributeTargets.Parameter)]
public class MaxItemsAllowed : ValidationAttribute
{
private readonly int maxCapacity;
public MaxItemsAllowed(int maxCapacity)
{
this.maxCapacity= maxCapacity;
ValidationFunc = ValidateMaxAllowedItems;
}
private bool ValidateMaxAllowedItems(Object value)
{
var contentArea = value as ContentArea;
var isValidCount = contentArea == null
|| contentArea.Items == null
|| contentArea.Count <= maxCapacity;
if (!isValidCount)
ErrorMessage = string.Foramt("{0} has more than ", items limit");
return isValidCount;
}
}
}

To create a validation rule, all you need to do is to create a new class inheriting from ValidationAttributeand override the 2 IsValid methods.

[AllowedTypes(typeof(CarouselSlide))]
[MaxItemsAllowed(5)]
public virtual ContentArea SlideItems{ get; set; }

The MaxItemsAllowed attribute can then be used to decorate the content area you care about. This method is probably the way I would recommend going.

Validating using IValidate

As of Episerver 7 there is also another way of validating a content area, this way using the IValidate interface.  Create a new class and inherit from IValidate.  On application start, EPiServer scans the solution for class that implement EPiServer.Validation.IValidate and executes the Validate() method.  This works the same way as the Page Type builder model, if a class is decorated as a ContentType, it gets picked up. The IValidate method will be called any time a page or block is saved.

In your validate method, you simply specify the page type you want to filter by and then put the code inside it.

public class ContentPageValidator : IValidate<ContentPage>
{
public IEnumerable<ValidationError> Validate(ContentPage page)
{
if (page.ContentArea != null && page.ContentArea.Count <= maxCapacity)
{
return new ValidationError[]
{
new ValidationError()
{
ErrorMessage = "Too many blocks have been added",
PropertyName = page.GetPropertyName<StandardPage>(p => p.ContentArea),
Severity = ValidationErrorSeverity.Error,
ValidationType = ValidationErrorType.StorageValidation
}};
}
return Enumerable.Empty<ValidationError>();
}
}

That should do you fine.  I prefer putting the attribute on the ContentArea class approach as it gives you less code duplication, but both ways work well.

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

More Posts

1 reply

Trackbacks & Pingbacks

  1. […] If you are interested in the ValidationAttribute I have written more about it in, How to Create a Custom Content Area Validator in EpiServer? […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *