· CMS13 Optimizely CMS

Optimizely CMS 13 breaking changes: IValidate<T>

When upgrading from Optimizely CMS 12 to CMS 13, you’ll encounter several breaking changes.

One easy-to-miss change is that custom validators (using the IValidate<T> interface) are no longer automatically discovered and executed as they were in CMS 12. As a result, they will not run unless they are explicitly registered in the dependency injection container.

Given the following validator:

public class ImageValidator : IValidate<PageData>
{
    IEnumerable<ValidationError> IValidate<PageData>.Validate(PageData pageData)
    {
        var localizationService = ServiceLocator.Current.GetInstance<LocalizationService>();
        var propertyDefinitionRepository = ServiceLocator.Current.GetInstance<IPropertyDefinitionRepository>();
        var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();

        foreach (var property in pageData.Property)
        {
            var xhtmlString = (property as PropertyXhtmlString)?.XhtmlString;
            if (xhtmlString == null)
            {
                continue;
            }

            var hasImage = xhtmlString.Fragments
                .OfType<UrlFragment>()
                .SelectMany(f => f.ReferencedPermanentLinkIds)
                .Any(guid => contentLoader.TryGet(guid, out ImageData _));

            if (!hasImage)
            {
                continue;
            }

            var propertyDefinition = propertyDefinitionRepository.Load(property.PropertyDefinitionID);
            var propertyDisplayName = propertyDefinition?.EditCaption ?? propertyDefinition?.Name ??  property.Name;
            yield return new ValidationError
            {
                ErrorMessage = $"The property {propertyDisplayName} shouldn't contain any images!",
                PropertyName = property.Name,
                Severity = ValidationErrorSeverity.Error
            };
        }
    }
}

To ensure that the validator is executed, it must be registered in Startup.cs:

services.AddCmsValidator<ImageValidator>();

With the above update, the resulting validation message still look like this:Graphical user interface, PowerPoint