World is now on Opti ID! Learn more

Daniel Ovaska
Aug 23, 2016
  2680
(0 votes)

A few hints about custom properties and StringList

This will be a small blog post about an error you might encounter when creating custom properties with EditorDescriptors.

I just got a weird error on one of my sites. StringList (the custom property in Alloy project) just stopped working in edit mode. Instead of the usual textbox where you add your input it displayed a button that said “Click the button to edit” and pressing it crashed the editor with a funny

[NullReferenceException: Object reference not set to an instance of an object.]
   EPiServer.UI.Edit.EditProperty.SetupPropertyControl(PropertyData property, PropertyDataCollection properties)

Yey! Now what?

Some background on custom properties first. As you might know, to make a custom property in Episerver you need both a c# class for your property like

/// <summary>
/// Property type for storing a list of strings
/// </summary>
/// <remarks>For an example, see where this property type is used for the MetaKeywords property</remarks>
[EditorHint(Global.SiteUIHints.Strings)]
[PropertyDefinitionTypePlugIn(Description = "A property for list of strings", DisplayName = "String List")]
public class PropertyStringList : PropertyLongString
{
...
}

This will basically tell Episerver how to store your data and not much more. The actual editor you see in edit mode is created by a few other componenent. First we have the EditorDescriptor:

/// <summary>
/// Register an editor for StringList properties
/// </summary>
[EditorDescriptorRegistration(TargetType = typeof(String[]), UIHint = Global.SiteUIHints.Strings)]
public class StringListEditorDescriptor : EditorDescriptor
{
    public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
    {
        ClientEditingClass = "alloy/editors/StringList";

        base.ModifyMetadata(metadata, attributes);
    }
}

This will let Episerver know which editor you want to use for a property that returns a string[] and has a specific UIHint. The ClientEditorClass is a key that is used to located the correct javascript file to use. You will then need the module.config to give Episerver a hint about where to locate your custom js/css files. These are located below /ClientResources/... in the alloy project. You can check them out there.

<?xml version="1.0" encoding="utf-8"?>
<module>
    <assemblies>
	    <!-- This adds the Alloy template assembly to the "default module" -->
        <add assembly="Alloy" />
    </assemblies>
    <clientResources>
        <add name="epi-cms.widgets.base" path="Styles/Styles.css" resourceType="Style"/>
    </clientResources>
    <dojo>
        <!-- Add a mapping from alloy to ~/ClientResources/Scripts to the dojo loader configuration -->
        <paths>
            <add name="alloy" path="Scripts" />
        </paths>
    </dojo>
</module>


Somewhere here, something went wrong and the editor just refused to show but where? After some head scratching I finally found the reason. Someone had set a UIHint on the actual property because they wanted to create a custom display template for the property.

[Display(
    GroupName = Global.GroupNames.MetaData,
    Order = 200)]
[CultureSpecific]
[BackingType(typeof(PropertyStringList))]
[UIHint("MetaKeywords")] //Problem...remove this!
public virtual string[] MetaKeywords { get; set; }

So far so good. This though will then override the default EditorHint that is set on class level in the background (to StringList in our case; check out PropertyStringList property above)...and that will then make the EditorDescriptor fail because it's set to only hook on if the property is of type string[] AND has the UIHint of StringList. No editor descriptor means that the StringList.js won't load in edit mode etc which is another symptom you might want to look out for. Removing the custom UIHint on property level and instead setting what display template to use in the view worked great!

<meta name="keywords" content="@Html.DisplayFor(m => m.CurrentPage.MetaKeywords,"MetaKeywords")">
So to sum it up. If you run into a similar error on your custom properties, avoid setting the UIHint on the actual property and set what custom template to use in the view instead and you'll be safe :) Easy pezy! Hope that saves a few, not so fun, hours for someone...

Happy coding!
Aug 23, 2016

Comments

Please login to comment.
Latest blogs
Make Global Assets Site- and Language-Aware at Indexing Time

I had a support case the other day with a question around search on global assets on a multisite. This is the result of that investigation. This co...

dada | Jun 26, 2025

The remote server returned an error: (400) Bad Request – when configuring Azure Storage for an older Optimizely CMS site

How to fix a strange issue that occurred when I moved editor-uploaded files for some old Optimizely CMS 11 solutions to Azure Storage.

Tomas Hensrud Gulla | Jun 26, 2025 |

Enable Opal AI for your Optimizely products

Learn how to enable Opal AI, and meet your infinite workforce.

Tomas Hensrud Gulla | Jun 25, 2025 |

Deploying to Optimizely Frontend Hosting: A Practical Guide

Optimizely Frontend Hosting is a cloud-based solution for deploying headless frontend applications - currently supporting only Next.js projects. It...

Szymon Uryga | Jun 25, 2025

World on Opti ID

We're excited to announce that world.optimizely.com is now integrated with Opti ID! What does this mean for you? New Users:  You can now log in wit...

Patrick Lam | Jun 22, 2025

Avoid Scandinavian Letters in File Names in Optimizely CMS

Discover how Scandinavian letters in file names can break media in Optimizely CMS—and learn a simple code fix to automatically sanitize uploads for...

Henning Sjørbotten | Jun 19, 2025 |