EPiServer  /  CMS February 01, 2010

A common problem with Page Type Builder and UniqueValuePerLanguage set to false

I’ve gotten quite a few questions lately regarding a problem where (code) properties that have the UniqueValuePerLanguage property in the PageTypeProperty attribute has been set to false returns null for pages that are in a different language than the master language. Although I understand the confusion this is actually by design, although I’m starting to have some doubts whether that decision was correct.

I’ll give some background on this issue shortly, but if you’re eager for a solution let me first tell you that it’s to implement your property like this:

[PageTypeProperty(UniqueValuePerLanguage = false)]
public string MyProperty
{
    get
    {
        returh this.GetPropertyValue(page => page.MyProperty, true);
    }
}

Background

EPiServer has two ways of fetching the value of a property. One is through the the Item/string indexer property or the Property property, like this:

object value = pageData["propertyName"];
//or like this
object value = pageData.Property["propertyName"].Value;

The other is by using the PageData.GetValue() method, like this:

object value = pageData.GetValue("propertyName");

There is an important difference between these two methods of retrieving property values. The first one will return the value of a property with the specified name in the PageData objects own PropertyDataCollection OR from a property returned from a GetPropertyDelegate. The second method, GetValue(), on the other hand will only return the value of a property from the PageData objects own collection of properties.

That is, using GetValue() will return values that are guaranteed to come from a property on the PageData object itself. The first method, using the string indexer or Property property on the other hand will first look for a property with a value on the PageData object itself but then also try to find a property with a value using a GetPropertyDelegate. As default this delegate is a method that will check for a value in three ways. It will first check if the requested property isn’t language specific and if the value exists in the master language. Then it will check if the page is of the “fetch data from” type and if so return a value from the page it’s supposed to fetch data from. Thirdly, it will try to return a value from a dynamic property with the same name.

As you might have guessed doing everything that the default GetPropertyDelegate does isn’t free of charge performance wise. Therefore I usually try to use GetValue() and only use the string indexer when I know I need to. This is also one of the reasons why I decided to implement the GetPropertyValue() method in Page Type Builder so that it uses GetValue(). That’s also how automatic properties (get; set;) are implemented. There is however an overload to GetPropertyValue() that accepts a Boolean argument with which you can specify if a GetPropertyDelegate should be used or not.

Possible future changes to this behavior

While I think it’s good to encourage people to stay away from dynamic properties (and PTB offers an alternative) this is by far the most common question that I’ve gotten regarding Page Type Builder except “how’s the performance” (good by the way :-)). I think the reason for this is that people are used to using the string indexer to fetch property values and therefore the standard behavior in PTB differs from EPiServer’s standard behavior. With that said, I’m not sure what’s the best way to solve this.

I see a number of possible ways to tackle this in version 1.2:

  1. Keeping the current implementation. This means that PTB’s standard implementation will be the one that has the best performance but developers of multilingual sites will have to actively consider how they implement their properties.
  2. Changing it so that GetPropertyValue() and automatic properties (get; set;) will use GetPropertyDelegates as default. This will probably be perceived as more “EPi-standard” but will add unnecessary overhead for properties that don’t need it.
  3. One of the above as standard but an option to change it to the other at startup (or in the application configuration, but I think this is a detail that is best configured in code).
  4. Either alternative one or two but with the ability to change it for each property in the PageTypeProperty attribute (via a property such as “UseGetPropertyDelegates = true/false).

Any well motivated opinions or other input on this is much welcome!

PS. For updates about new posts, sites I find useful and the occasional rant you can follow me on Twitter. You are also most welcome to subscribe to the RSS-feed.

Joel Abrahamsson

Joel Abrahamsson

I'm a passionate web developer and systems architect living in Stockholm, Sweden. I work as CTO for a large media site and enjoy developing with all technologies, especially .NET, Node.js, and ElasticSearch. Read more

Comments

comments powered by Disqus

My book

Want a structured way to learn EPiServer 7 development? Check out my book on Leanpub!

More about EPiServer CMS