There are many funny details to be aware of when upgrading from Episerver CMS 11 to Optimizely CMS 12. One of them that might feel a bit confusing is when your list items start to have all required fields in the UI. Here's how to fix it.
When upgrading a CMS 11.* (or earlier) site to CMS 12 and .NET 6/7/8 there are many (!) pitfalls and interesting things to be aware of.
I've recently completed a major 1:1 upgrade project and I'll try to blog a few of the most typical issues - starting with this one, cause at first it seemed very strange to me.
Customizing property types is extremely common - and one of the most common things to do is to use the classic "Complex property list" hack. I've blogged about it before and so have many others - and even officially "unsupported" it even has had it's own place in Optimizely's documentation.
A typical implementation could look like this:
public class CustomListItem
{
[Display(Name = "Title")]
public string Title { get; set; }
public string Description { get; set; }
}
[PropertyDefinitionTypePlugIn(GUID = "970FFB85-0DC7-4F25-B41F-18C4B9688567")]//Important: Remember GUID before upgrade
public class CustomListItemPropertyDefinition : PropertyList<CustomListItem> { }
public class MyCollectionEditorDescriptor : CollectionEditorDescriptor<CustomListItem>
{
}
And be used like this:
[EditorDescriptor(EditorDescriptorType = typeof(CollectionEditorDescriptor<CustomListItem>))]
public virtual IList<CustomListItem> ListItems { get; set; }
Which results in an editorial experience like this:
Behind the scenes what this does it to basically serialize the poco objects to json and store them in a string property on the content.
This is not really ideal - especially since there now is a better approach in CMS 12 where you can basically keep a list of inline blocks of a certain type - which is 'properly' stored behind the scenes. But when upgrading it's not easy to convert one approach to the other due to all the existing content.
So - you typically find yourself having to upgrade the solution.
First thing you want to remember is to check if your old CMS 11 solution had remembered to set the PropertyTypeDefinition GUID. It really should. Because if it doesn't and you take the upgrade as an opportunity to clean up a bit and change some namespaces or similar then the PropertyTypes will no longer match up and content is lost.
The other thing is a funny little detail that can give you an early onset of grey hairs - you might get confused error reports from testers/editors wondering why their list items all of a sudden have a lot of required fields, that didn't used to be required. Like this:
"Why is that?" you wonder and re-check that you didn't add any validation rules or [Required] tag to any of the properties in the POCO object. At least that was my reaction.
After trying a bunch of different things I though - why not try to make the properties in the POCO item nullable - and voila, that solved it. And it sort-of made sense.
But not until after Palle and I investigated it in more depth did it really make sense to me. Turns out that this happens when the project has the Nullable mode enabled.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
With that mode enabled, .NET no longer supports that reference types such as strings can be null, unless declared as Nullable - and magically this is even handled in Edit Mode UI. When Optimizely can't set a property as null, obviously it must be required.
Recent posts