Linus Ekström
Mar 30, 2011
visibility 5188
star star star star star
(1 votes)

Property Validation and IPropertyPreferLoadData

When the EPiServer property system was rewritten in the EPiServer CMS 5 release properties was split into two parts: one core class that handled the data and one class responsible for creating UI: s. One question I got several times, specially after the CMS 5 release was how to implement input validation on the server. Should it end up in the core property or in the property control? Using the built in asp.NET validators it’s pretty simple setting up different validators in the property control that can validate both on the client as well as on the server.

But what if you have code setting the property’s value that does not use the property’s property control but rather set the value of the property directly, or perhaps through a custom UI on the web site? The simple solution is of course to do input validation in the property’s Value setter. This might have some side effects though.

An example

EPiServers built in PropertyDocumentUrl and PropertyImageUrl properties have validation that the value of the property is an URL that actually points to an existing file within the EPiServer CMS file system. When working with the improved on page edit functionality in EPiServer CMS 6 R2 we decided to move file validation from the property controls to the actual properties. This had some side effects though. When importing data for instance, the property value was actually set before the import of the referenced file which would cause an exception.

IPropertyPreferLoadData

There already exists an interface called IPropertyPreferLoadData in the EPiServer.Core namespace. This is a marker interface that informs users of the property that it prefers using the LoadData method when initializing the property instead of setting the data through the Value property. In CMS 6 this is used when loading data from the database but unfortunately not when importing/mirroring data. This has been changed in EPiServer CMS 6 R2 so that it works the same way for page loads and data imports. This makes is possible to add validation in the Value property setter but bypassing the validation (if desired) in the LoadData method.

The solution for the URL classes

PropertyUrl implements logic that calls an empty, virtual method called ValidateUri in the Value setter. PropertyDocumentUrl and PropertyImageUrl now inherits from the abstract class PropertyFileUrl. PropertyFileUrl implements IPropertyPreferLoadData and adds logic to the ValidateUri method. In short, this is how the classes looks like:

   1: public class PropertyUrl : PropertyString, IReferenceMap
   2: {
   3:     protected override string String
   4:     {
   5:         set
   6:         {
   7:             //Some code to handle permenent links etc.
   8:             ValidateUri(value);
   9:             base.String = value;
  10:         }
  11:     }
  12:     public override void LoadData(object value)
  13:     {
  14:         base.String = value as string;
  15:     }
  16:     protected virtual void ValidateUri(Uri uri)
  17:     {
  18:     }
  19: }
   1: public abstract class PropertyFileUrl : PropertyUrl, IPropertyPreferLoadData
   2: {
   3:     protected override void ValidateUri(Uri uri)
   4:     {
   5:         try
   6:         {
   7:             // Check if file exists with decoded value since the file won't be found otherwise.
   8:             bool fileExists = EPiServer.Web.Hosting.GenericHostingEnvironment.VirtualPathProvider.FileExists(uri.LocalPath);
   9:             if (!fileExists)
  10:             {
  11:                 throw new FileNotFoundException(String.Format(LanguageManager.Instance.Translate("/validation/filenotfound"), TranslateDisplayName()));
  12:             }
  13:         }
  14:         catch (Exception)
  15:         {
  16:             throw new FileNotFoundException(String.Format(LanguageManager.Instance.Translate("/validation/invalidvalue"), TranslateDisplayName(), uri.ToString()));
  17:         }
  18:     }
  19: }

Validation rules that changes

Another scenario where this would be an useful approach is where data validation rules might change. For instance, you want to create a property where the user should set an integer. The min and max value of the integer is defined by property settings. With this scenario data that was valid yesterday is not longer valid since the property settings might change. In EPiServer CMS 6 this would work fine if validation was implemented in the property control but when implemented in the property would throw an exception when loading the property from the database if the stored data was no longer valid. With the same approach as the property URL classes this should now work fine when implemented in the core property class.

Mar 30, 2011

Comments

error Please login to comment.
Latest blogs
Extending a Contract: What You Can Override

Contracts share fields across content types — but not every field setting can be overridden. Push the same contract onto several components, and CM...

Chirag Khanna | Sep 18, 2026 |

Building a Blazor Server UI Inside the Optimizely CMS 13 Admin Shell

What I learned shipping a Blazor Server UI inside Optimizely CMS 13 — Razor components in a NuGet package, the Blazor hub next to MapContent(),...

Stanisław Szołkowski | Sep 17, 2026 |

Giving Optimizely 13 Content Types Meaningful Icons and Thumbnails

When working with an Optimizely CMS solution that has evolved over time, it is common to end up with many content types. As the number grows, the...

Pär Wissmark | Sep 16, 2026 |

force-dynamic vs connection() for Optimizely Graph

If you have built an Optimizely CMS SDK site, you already know getContentByPath on a catch-all. This post is about the part that file never says ou...

Chirag Khanna | Sep 16, 2026 |

I built a thing - nOSC & nOCP - an experiment?

I don't think I'm always that convensional . And that's where this starts... So firstly, I was lucky enough to see OCP UI extensions for Optimizey...

Matt Pallatt | Sep 15, 2026

A day in the life of an Optimizely OMVP: OptiA11y: accessibility help for Optimizely editors that refuses to lie to them

Most accessibility tooling in the CMS space has the same shape. A crawler walks your published site, renders each page, runs axe-core over the DOM,...

Graham Carr | Sep 15, 2026