Confusing handling of empty/null properties

Found in

EPiServer.CMS.Core 9.9.0

Fixed in

EPiServer.CMS.Core 10.0.1


Jun 03, 2016


Oct 27, 2016


CMS Core


Closed, Fixed


Create a content type with a list property, like:

[ContentType(GUID = "1B05596D-EB55-41A4-BA3A-2EA06A2D0688")]
public class TestPage : PageData
    public virtual IList<ContentReference> MyReferences { get; set; }

Now, when trying to work with this collection, it behaves in surprising ways, since it considers itself null whenever empty:

IList<ContentReference> myReferences;
page = ContentRepository.GetDefault<TestPage>(ContentReference.StartPage);
page.MyReferences = new List<ContentReference>();
// page.MyReferences.Add(new ContentReference(1)); // exception! because:
myReferences = page.MyReferences; // null
page.MyReferences = new List<ContentReference> {new ContentReference(1)};
page.MyReferences.Add(new ContentReference(2)); // ok! because collection was not empty before
myReferences = page.MyReferences; // not null
myReferences = page.MyReferences; // null

This means it is impossible to help consumers of the content type by initializing the collection in SetDefaultValues (because putting an empty collection in results in null).

It would be much nicer to work with the list property type if it were initialized with an empty collection when the content object is new, or when it is loaded with a null value for the PropertyData.

Breaking changes

  • Value type based properties were changed to support nullable value types (PropertyBoolean, PropertyDate, PropertyFloatNumber, PropertyNumber). This means that it is now possible to distinguish if a nullable property has been assigned with its default value (e.g., false, 0) or not assigned.
  • Behavior of properties was consolidated so getter/setter work as standard .NET properties (PropertyContentReferenceList, PropertyCategory, PropertyListCollection). Previously, some collection properties returned null from getter when an empty collection was assigned through setter.
  • PropertyData implementations were changed to behave more consistently between typed accessor and Value accessor. Previously, Value property could return null while the typed accessor returned a value (for example, for empty collections for collection properties).