Skip to content

Define Properties on Content Types

⏱ 20 minutes intermediate
📜Corecms

Properties define what authors can enter for each content type. Well-configured properties make the authoring experience intuitive — with clear labels, sensible defaults, helpful descriptions, and validation that catches errors before publishing. Poorly configured properties lead to inconsistent content, author frustration, and bugs in rendering.

C# TypeCMS propertyEditor controlUse for
stringShort stringText inputTitles, names, short labels
XhtmlStringRich textTinyMCE editorBody content with formatting
ContentReferenceContent linkContent pickerLinking to another page or media
ContentAreaContent areaDrag-and-drop zoneComposable block regions
UrlURLURL pickerExternal links, downloads
boolBooleanCheckboxFeature toggles, visibility flags
int / doubleNumberNumber inputCounts, measurements, prices
DateTimeDate/timeDate pickerEvent dates, deadlines
IList<string>String listTag editorTags, categories

The [Display] attribute controls how a property appears in the editor.

Property display configuration
csharp
[Display(
    Name = "Page Title",           // Label shown in editor
    Description = "The main heading displayed at the top of the page",
    GroupName = SystemTabNames.Content,  // Which tab
    Order = 10,                    // Position within the tab
    Prompt = "Enter a descriptive title")]  // Placeholder text
[Required]
[StringLength(100, MinimumLength = 5)]
public virtual string PageTitle { get; set; }
Common validation patterns
csharp
// Required field — publish blocked without value
[Required]
public virtual string Title { get; set; }

// String length limits
[StringLength(160, ErrorMessage = "Meta description must be under 160 characters")]
public virtual string MetaDescription { get; set; }

// Range validation for numbers
[Range(1, 100, ErrorMessage = "Must be between 1 and 100")]
public virtual int DisplayOrder { get; set; }

// Regular expression validation
[RegularExpression(@"^#[0-9A-Fa-f]{6}$", ErrorMessage = "Must be a hex color code")]
public virtual string AccentColor { get; set; }

Group related properties into tabs so the editing form stays manageable.

Custom tab groups
csharp
// Define custom tab names
public static class SiteTabNames
{
    public const string SEO = "SEO";
    public const string Settings = "Settings";
    public const string Social = "Social Media";
}

// Use in properties
[Display(Name = "Meta Title", GroupName = SiteTabNames.SEO, Order = 10)]
public virtual string MetaTitle { get; set; }

[Display(Name = "Open Graph Image", GroupName = SiteTabNames.Social, Order = 10)]
public virtual ContentReference OgImage { get; set; }

[Display(Name = "Hide from Navigation", GroupName = SiteTabNames.Settings, Order = 10)]
public virtual bool HideFromNav { get; set; }
Property defaults
csharp
public override void SetDefaultValues(ContentType contentType)
{
    base.SetDefaultValues(contentType);
    HideFromNav = false;
    DisplayOrder = 100;
    PublishDate = DateTime.Now;
}

For properties with predefined choices, use selection factories.

Dropdown selection property
csharp
// Define the options
public class ColorSelectionFactory : ISelectionFactory
{
    public IEnumerable<ISelectItem> GetSelections(
        ExtendedMetadata metadata)
    {
        return new ISelectItem[]
        {
            new SelectItem { Text = "Primary Green", Value = "primary" },
            new SelectItem { Text = "Dark", Value = "dark" },
            new SelectItem { Text = "Light", Value = "light" },
        };
    }
}

// Use on property
[SelectOne(SelectionFactoryType = typeof(ColorSelectionFactory))]
[Display(Name = "Color Theme", Order = 60)]
public virtual string ColorTheme { get; set; }