Try our conversational search powered by Generative AI!

Johan Björnfot
May 22, 2018
  3571
(7 votes)

IContentSaveValidate - validation with context

This time I thought I should share a tip about a component IContentSaveValidate<TContent> that we added a while ago but that perhaps not all are aware of. 

In CMS 7 we added the EPiServer.Validation.IValidate<T> interface, which has a signature like:

 /// <summary>
    /// Defines the signature for a component that validates instances of <typeparamref name="T"/>.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IValidate<T> : IValidate
    {
        /// <summary>
        /// Validates the specified instance.
        /// </summary>
        /// <param name="instance">The instance.</param>
        /// <returns></returns>
        IEnumerable<ValidationError> Validate(T instance);
    }

The idea with the interface was to make it possible to extend the validation possibilities offered by validation attributes. So when calling IValidationService.Validate for an item then will the service first locate all registered validators that has a generic type parameter T which the item can be assigned to and then call validate on them. So say for example that we are validating an instance of StandardPage then would validators implementing IValidate<StandardPage>, IValidate<PageData> and IValidate<IContent> be called but not a validator implementing IValidate<IContentMedia>.

The IValidate<T> interface does not have any type constraint but it is most commonly used during save of content instances. However there might be cases where you want to do the validation only for certain state transitions, for example when the content is published. With IValidate<T> it is not possible to distinguish which state transition it is (if any). Therefore we introduced the more specialized interface IContentSaveValidate<TContent> that looks like:

public interface IContentSaveValidate<TContent> : IContextValidate<TContent, ContentSaveValidationContext>
        where TContent : IContentData
    {
        /// <summary>
        /// Validates the specified instance given specified context
        /// </summary>
        /// <param name="instance">The instance that is validate</param>
        /// <param name="context">The context for the validation</param>
        /// <returns>A list of validation errors or empty list if instance is valid</returns>
        IEnumerable<ValidationError> Validate(TContent instance, ContentSaveValidationContext context);
    }

Now in addition to the content item to validate you also get a context where you can get the state transtion from. Below is an example of an implementation that only validates when a StandardPage is published.

    [ServiceConfiguration(IncludeServiceAccessor = false)]
    public class StandarPagePublishedValidator : IContentSaveValidate<StandardPage>
    {
        private readonly IStatusTransitionEvaluator _statusTransitionEvaluator;

        public StandarPagePublishedValidator(IStatusTransitionEvaluator statusTransitionEvaluator)
        {
            _statusTransitionEvaluator = statusTransitionEvaluator;
        }

        public IEnumerable<ValidationError> Validate(StandardPage instance, ContentSaveValidationContext context)
        {
            var transition = _statusTransitionEvaluator.Evaluate(instance, context.SaveAction);
            if (transition.NextStatus == VersionStatus.Published)
            {
                //do validation for publish here
            }
            return Enumerable.Empty<ValidationError>();
        }
    }



May 22, 2018

Comments

Please login to comment.
Latest blogs
Why C# Developers Should Embrace Node.js

Explore why C# developers should embrace Node.js especially with Optimizely's SaaS CMS on the horizon. Understand the shift towards agile web...

Andy Blyth | May 2, 2024 | Syndicated blog

Is Optimizely CMS PaaS the Preferred Choice?

As always, it depends. With it's comprehensive and proven support for complex business needs across various deployment scenarios, it fits very well...

Andy Blyth | May 2, 2024 | Syndicated blog

Adding market segment for Customized Commerce 14

Since v.14 of commerce, the old solution  for adding market segment to the url is not working anymore due to techinal changes of .NET Core. There i...

Oskar Zetterberg | May 2, 2024

Blazor components in Optimizely CMS admin/edit interface

Lab: Integrating Blazor Components into Various Aspects of Optimizely CMS admin/edit interface

Ove Lartelius | May 2, 2024 | Syndicated blog

Anonymous Tracking Across Devices with Optimizely ODP

An article by Lead Integration Developer, Daniel Copping In this article, I’ll describe how you can use the Optimizely Data Platform (ODP) to...

Daniel Copping | Apr 30, 2024 | Syndicated blog

Optimizely Forms - How to add extra data automatically into submission

Some words about Optimizely Forms Optimizely Forms is a built-in add-on by Optimizely development team that enables to create forms dynamically via...

Binh Nguyen Thi | Apr 29, 2024