Home » .NET | Daniel | EPiServer

How to safely retrieve page data properties in EPiServer CMS

21. December 2009 by Daniel Berg 6 Comments

This post is about retrieving EPiServer CMS PageData properties in a safe way using generics and extension methods.

Retrieving PageData properties in EPiServer CMS

Retrieving EPiServer CMS PageData properties is simple. With the PageData object we can request the property with a string index. The PageData object will return the property as System.Object so you’ll need to cast that object into the type you need.

In the code sample below we retrieve a property on the current page and cast it as a page reference object.

PageReference myPageRefProperty = (PageReference)CurrentPage["MyPageReferenceProperty"];

This won’t throw any errors because if the property does not exist the page object will return null which is valid for a reference type such as the PageReference type. Thus the myPageRefProperty variable will only be null.

But what if we then decided to use myPageRefProperty? Like so:

int pageId = myPageRefProperty.ID;

Now this will throw a NullReferenceException because you can’t request a property on an object that is null!

image

Another exception scenario is if we try to retrieve a property as a boolean (or any other value type) and the property shouldn’t exist. Since a boolean is a value type it isn’t allowed to be null unless declared as nullable. The following code will result in an exception if the property doesn’t exist.

bool myBool = (bool)CurrentPage["IsPageAwesome"];

image

Generics and extension methods

Let’s see what we can use in .NET 3.5 with Generics and Extension Methods to solve this!

Generics

When requesting a page property we’d like to declare the type of the property before actually retrieving it. This is where generics comes into play. With generics we can create a method that doesn’t know what type will be returned. It just knows that some property will be returned.

Consider the following method signature:

private T MyMethod<T>(T someVariable)

T declares the Type the method should return and the Type of the someVariable. This is really cool!

Extension Methods

Extension methods can be added to existing types without the need of recompiling the original type. This means that we can add methods to the EPiServer.PageData type without actually recompiling that source code!

Let’s put all this to good use!

So. Let’s create a generic extension method for the PageData type to safely retrieve page properties.

public static T GetProperty<T>(this PageData page, string propertyName, T fallbackValue)
{
	try
	{
		if((T)page[propertyName] == null)
			return fallbackValue;
		else
			return (T)page[propertyName];
	}
	catch (Exception)
	{
		// An exception occurred when retrieving the property. Returning fallback!
		return fallbackValue;
	}
}

Let’s have a closer look at this extension method.

public static T GetProperty<T>(this PageData page, string propertyName, T fallbackValue)
  • The extension method must be declared as static.
  • T declares the Type we want to return.
  • this PageData page is the PageData object we’re calling the method on.
  • The input variable propertyName is the name of the property we want to fetch.
  • The input variable fallbackValue is the value we want the method to return in case the property couldn’t be retrieved.

This means that we can call the method like so on CurrentPage:

CurrentPage.GetProperty<bool>("SomePageProperty", true);

This method calls the extension method on CurrentPage, trying to fetch the property named SomePageProperty. If the property doesn't exist then it will return True.

Download the source code

Download the source code for this here. The PageExtensions class also includes extension methods that themselves declare the type. E.g. GetStringPageProperty. Which in return calls the generic method with the return type of String.

Comments

Ted Nyberg
Sweden Ted Nyberg said:

I like it!

A slightly revised code snippet could be:
[b]T propValue = CurrentPage["NameOfProperty"] as T ?? fallbackValue;[/b].

Cheers and Merry Christmas! :)

daniel
Sweden daniel said:

Thanks, Ted!

I agree! Readability is awesome. I suspect you, like me, cringed at those if-statements.

The problem is only that when using the "as"-operator the Type must be able to resolve as null.

We could use constraints on our generic type to enable this. But then we would lose the possibility of casting the property as value type and reference type.

And a merry one to you as well! :)

pingback
hellocms.com said:

Pingback from hellocms.com

Daniel Berg on .NET | How to safely retrieve page data properties … Hello CMS - the best cms website

Lars
Norway Lars said:

Isn't this pretty much the same as this approach http://labs.episerver.com/en/Blogs/Adam_Najmanowicz/Dates/111369/111370/111377/

Give the man some cred!

daniel
Sweden daniel said:

Hey Lars!

I had missed Adam's blog post about this. And, yes, the posts are quite similiar. They both highlight the use of generics when retrieving page data properties. This post also shows you how to implement the use of generics together with extension methods. I suppose great minds - ahem - think alike!

Thanks for pointing this out!  

pingback
194.defutbolazo.com said:

Pingback from 194.defutbolazo.com

55 Lens Nikon 70 300mm Vr, 200 Chrysler 300m

Add comment


(Will show your Gravatar icon)

  Country flag


  • Comment
  • Preview
Loading