November Happy Hour will be moved to Thursday December 5th.

Confusing handling of empty/null properties

Found in

EPiServer.CMS.Core 9.9.0

Fixed in

EPiServer.CMS.Core 10.0.1

(Or a related package)

Created

Jun 03, 2016

Updated

Jan 07, 2022

Area

CMS Core

State

Closed, Fixed


Description

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
page.MyReferences.RemoveAt(1);
myReferences = page.MyReferences; // not null
page.MyReferences.RemoveAt(0);
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).