Properties store and present data for content such as pages and blocks. You can store properties for a single content item or as a dynamic property that can be inherited.
When you define a property on a content type, Optimizely Content Management System (CMS) stores the property as a `PropertyDefinition
` class and backs runtime instances of the property type by types inheriting from `PropertyData
`. These classes deal with the data inside the property, such as protecting read-only state, preparing data from saving and loading, declaring value type, and so on. `PropertyData
` classes also can provide a default user interface.
## Access a property on a read-only page
CMS returns content items in read-only mode from the API. The following code shows how to access a property that resides on the `StandardPage
` property on `PageData
`:
The accessor determines whether the property with the name `PropertyName
` is a property on the page by checking `Property
` defined on `IContentData
` implemented by `PageData
` (from which `StandardPage
` inherits). It returns the property value, if one exists. If the property is not on the page, a delegate is called to see if the property is found elsewhere. The default delegate looks for the property from the **fetch data from**Â function (if activated on the current page). The delegate checks the dynamic properties for the page. You can write your own delegate and change this behavior.
## Access a property on a write-enabled page
If the page you are working with is write-enabled, the `Property
` accessor returns properties that are defined on the page; you never get dynamic properties or fetch data from properties when the page is in write mode.
## Access properties on strongly typed content
When you access properties on a strongly typed page, work with that page as you work with an ordinary .NET object. Given a strongly typed page with the following signature:
Note
Why is the property declared as virtual? In the background, a proxy class is created for the page type, where the typed property on your class is connected to the backing `
PropertyData
` instance. This only works if properties are declared as virtual otherwise they cant be overridden. If the properties are not declared virtual, you need to implement get/set so they read/write data to the underlying property collection instead.
If you are using the generic `EPiServer.Web.Mvc
` in your page inheritance, you can access the `MainBody
` property like this:
### Extension methods for strongly typed content
Use the `GetPropertyValue
`Â and `SetPropertyValue
` extension methods to take advantages of strongly typed models and also override the get and set behavior for the property. Add a `using
` statement referencing the `EPiServer.Core
`Â namespace to your class to use these extension methods.
The following example shows a strongly typed content model that has a fallback behavior for its `PageHeading
` property. If the editor sets the `PageHeading
` page property, the `PageHeading
` property on the model returns the set value. If the editor does not set it, the property on the model returns the `PageName
` property instead:
## Access properties on non-strongly typed content
If a property is unknown or if you want to access several properties (for example in a loop), you can access the value directly through its object representation.
If you know the type of your value, you can cast it directly.
If you are unsure of the actual type and want to avoid an exception, assign the property value with the **as** keyword:
Do not assume the value type for a property type. For example, values of `PropertyXhtmlString
` are of type `XhtmlString
`, not `string
`. So casting the value of a `PropertyXhtmlString
` to `string
` causes an exception, and using the **as** string operation yields null.
### Use the GetPropertyValue extension method for non-strongly typed content
The `EPiServer.Core
`Â namespace has extension methods for `ContentData
`. If you import the `EPiServer.Core
` namespace (for example with a **using** statement in code behind), it extends `ContentData
` with the `GetPropertyValue
`Â method, which can simplify property access by reducing the amount of code. For example, use `GetPropertyValue
` to get the string representation of a property without first checking against null, or to provide a default value if the property is null.
The following usage examples show different overloads of `GetPropertyValue
`:
## Use a property multiple times
If you access a property used multiple times in your code, you can save a reference to the property. Otherwise, the property is fetched from the internal collection for each call, which also may result in several unnecessary calls to the delegate if the property is not native to the page.
For example, use:
Instead of:
## Check null values in properties
CMS does not store properties with an empty value in the database. If you access a property from code, it is always null—not an empty string, 0, or false. This is because null is a very convenient way to check if something is not set by an editor or does not exist on this page. You just have to compare with null regardless of data type.
The following example throws a `NullReferenceException
` if the value is empty or missing:
`StringBuilder.Append
`Â accepts null objects so this example is better than the previous example:
The following example throws a `NullReferenceException
` if the value is empty or missing:
Markup accepts any type and converts to string, so you do not need cast:
The following example shows fallback for `src
` attributes:
To return a string, use the ?? operator as follows:
The following example returns a value type:
Another fallback in the markup using the ?? operator as follows:
## Update values for a page
If you want to update properties for an existing page, make sure that you have a writable version of the page, as shown in the following example.
To set new values, assign them directly to the `writablePage
` object by working against the properties for the most common page properties or by accessing the values directly:
This is the same as:
When you are done with the page, save it by using `IContentRepository
` (available in DI container):
Note
You cannot save dynamic properties or properties that reside on other pages when you are working against `
IContentRepository.Save
`.
## HTML encoding and CMS page properties
HTML has a special handling for characters such as \< > and symbols ? & /. Some browsers may truncate or corrupt spaces, or problems arise when the browser displays these types of characters. For your website to be XHTML valid, use the `HttpUtility.HtmlEncode
` method on strings that you inject with inline expressions. `HttpUtility.HtmlEncode
` is part of .NET Core. The `HtmlEncode
` method encodes a string that is displayed in a web browser.
When outputting strings directly in Razor views normally you do not need to encode string. Razor by default encodes strings outputted inside a code block. The following example shows how to display the CMS `Name
` property: