In this tutorial, you will learn about the different ways you can cast objects returned from the Episerver content querying APIs. You will learn about the different data types used by the CMS and the pros and cons of each object type. If this sounds good to you, read on 🔥🔥🔥
In Episerver all content has to inherit from the IContent
interface. Anything that implements IContent
can be queried from the database using either the IContentLoader
or IContentRepository
. If you are new to Episerver and you want to know more about these utilities, I recommend you read this tutorial.
To query the CMS for some content, you will typically be writing code like this:
This snippet will retrieve pages, blocks, images, videos and basically anything that inherits from IContent
. Using a generic data type approach like this can be really useful when you want to use the same code to work with lots of different types of dynamic content.
A good example of this usefulness is when you need to write code to process items contained within a content area. You will need a global way to interact with all of these objects in code. Writing code to cater for every single content type that could be added within the CMS, would create lots of if
statements and result in a lot of ugly spaghetti code. When you are dealing with lots of different types of Episerver content in a single list you will want an easy way to work with that data. In these instances, cast everything to IContent
The problem with this generic approach is that the IContent
interface can only supply properties that exist on everything. In Episerver these properties include ContentLink
, Name
, and ParentLink
. In a lot of situations, you can't do anything specific when dealing with an item of IContent
. This is when you need to type things from IContent
Episerver also provides a few lower-level abstractions. For example, all CMS pages will need to inherit from PageData
and all blocks will need to inherit from BlockData
. This means you can cast any page to PageData
. PageData
exposes a lot more properties compared to IContent
. These properties include PublishDate
, ExpiryDate
, IsPendingPublish
, LanguageBranch
, PageName
, URL
and URLSegment
. You can also cast any block to type BlockData
.
Casting To Specific DataTypes
To access all the data stored within the CMS about a specific page or a block, you will need to cast the object to its underlining data type. For example, if want to access the Title
property stored within a page type called StartPage
and the current item is typed to IContent
you can use this code:
You could cast it like this:
There's nothing complex about this code, however, if you know that your code will be of type StartPage
you may as well tell the Episerver API the format that you want it returned. This approach will give you access to all the data and it will save you from writing a few extra 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 codebase easier to read, however, there is one word of caution
When casting objects you need to keep in mind that you can get a TypeMismatchException
error if you screw it up. Say you have a content reference that is a ContentPage
page type, however, you think that it's a StartPage
. If you cast the object incorrectly, you will get this error:
` EPiServer.Core.TypeMismatchException: Content with id '206__CatalogContent' is of type 'Castle.Proxies.ContentPage' which does not inherit required type 'Model.Catalog.StartPage'
Always be wary when casting objects. As you can see when you work with Episerver content you have several different levels of abstractions you can work with. All content inherits from IContent
so you can always cast objects to this type.
The main problem with the IContent
interface is that it only exposes a limited amount of properties and it may not provide you with all the data you need. If you know you are working exclusively with pages or blocks, you can cast the object to either PageData
or BlockData
. Lastly, if you need a very specific property that directly relates to a certain type you can cast it directly.
You are now a casting Jedi. Go forth and cast 💥.Happy Coding 🤘