Different Ways Of Casting Objects From The Episerver Api

I have talked previously about getting objects from the Episerver API here.  In today's guide, I'm going to cover the different ways you can retrieve your data back and some of the pro's and con's with each approach.

The Cover All Scenario

In Episerver all content has to inherit from the IContent interface.   IN order to get the content item from the API you would call this code:
 var pageLink = new ContentReference();
 var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
 var content = contentLoader.Get<IContent>(pageLink);
This snippet will work for retrieving any page, block, image, video and basically anything that inherits from IContent.  Using a generic approach can be really useful when you are working with dynamic content, a good example of this is when you're processing items that a content editor has added into a content area.  You won't know the content types, the order etc.. The problem with this generic approach is that the IContent interface only supplies a limited number of properties, like ContentLink, Name, Parent Link.  While using IContent it create for dealing with an unknown quantity of Episerver content, in most situations you can't do anything useful with it unless you cast it.

Generic Page and Blocks

When you get content from the API 90% of the time it will either be a page or a block and working with IContent does not give you access to enough properties. Episerver also provides a higher level abstraction, all pages inherit from PageData and all block inherit from BlockData. This means if you want a few generic properties about a list of pages you can cast it to PageData. PageData exposes properties such as publish date, expiry date, is pending publish, language branch, page name, url and url segment. If you were working on a mega menu block using the API at a PageData level is a lot more beneficial than working with IContent. Sometime though you need to work directly with a specific page or block type.

Casting To Specific DataTypes

If you want access to a specific item in Episerver, like you want information only stored on the StartPage, like the websites title, then you will then need to cast the page to the correct type:

   public class StartPage: PageData
       public virtual string Example{ get; set; }

 var pageLink = new ContentReference();
 var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
 var startpage = contentLoader.Get<StartPage>(pageLink);


There's nothing complex about that code but if you know that your code will always return a StartPage you may as well tell the Episerver API the format you want it in and save yourself a few lines of code: The benefit of working directly with the object is that you will get all of its properties without having to do any additional casting, boxing or jiggery-pokery.  This generally results in more efficient code, reduces bugs and makes your code base easier to read, however, there is one word of caution. When we work directly with the object you need to keep in mind that you can get TypeMismatchException if you screw it up. Say you have a content reference that is a ContentPage page type but you think that it's a StartPage.  If you used the code above you would see this error: EPiServer.Core.TypeMismatchException: Content with id '206__CatalogContent' is of type 'Castle.Proxies.ContentPage' which does not inherit required type 'GMGShop.Model.Catalog.StartPage'


That covers today's guide; as you can see when you work with Episerver content you have several different levels of abstraction you can work with. All content inherits from IContent so when we work with the API we can always cast objects to this type. The main problem with the IContent interface is that it only exposes a limited amount of properties that may not provide you with everything you need without doing further casting. If you know you are working exclusively with pages or blocks, you can cast to either PageData and BlockData. These properties expose a lot more useful properties. Lastly, if you need a very specific property that directly relates to a certain type you can cast it directly.  If you get the casting wrong EpiSErver will throw a TypeMismatchException. If you do not know the page type of an item you are working with you can safely load it with IContent as type argument.  If you do then working with that types will make your code easier to read and more efficient.

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

Back to top
var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-35662136-1']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })();