In this tutorial, you will learn the recommended way to compare two objects of type ContentReference
within Episerver CMS. In order to understand how to properly compare content references, we need to take a bit of a deep dive into the make-up of a ContentReference
. If this sounds interesting to you, read on 🔥🔥🔥
What Is A Content Reference?
A ContentReference
is an out-of-the-box data object type that ships with Episerver CMS. A ContentReferene
is used to reference content within an Episerver website. In the early days of Episerver, a content reference only referenced pages. Since Episerver v7, the IContent
interface was introduced and now a content reference object may reference pages, blocks, images, videos and whatever content you want to work with within your CMS. This could be a page, block, an image or even custom data within a service that sits outside of Episerver. 🤔
When a class implements the IContent
interface it can be used with the Episerver APIs and it can be saved into the Episerver database. When content is saved, a corresponding entry is made within the Episerver database and a unique numeric primary key is associated with that bit of content. One way to query a specific bit of content from Episerver CMS is via this primary key ID
. To do this you can call the API, bypassing in a ContentReference
object and setting the ID. The API will return the content. For example, if the database ID of a page is 4, you create a new ContentReference
object, setting ID
to 4
and then using IContentReportistory.Get()
you can query the CMS:
Now you know how to query content, what happens if we want to compare if two content references to make sure they reference the same bit of content? You may very well be tempted to do this using this code:
This might look like a perfectly logical bit of code, however, it contains a very subtle bug. All Episerver databases ID's are unique, however, it is also possible to import content into Episerver from third-party sources. This is possible via a content provider. When you have two data sources, in theory, it is possible for two bits of content to have the same numeric ID. This is why we need to differentiate content by the ID
and its data source.
If you look within the ContentReference
class definition, you will find a property called ProviderName
. The provider name is the way you can differentiate between the different data sources. This is why comparing ContentReference
using a ==
comparison using ID
alone is a mistake 😔
The issue with a compression solely on ID
is that in the future if a content provider was introduced, an ID
clash could occur and your code could work in an unexpected way. With a second content source, it would be possible to have two bits of content with an ID of 2. Granted this is a very unlikely situation, however, the point is that in order to write safe code, you need to compare by provider name and the ID to ensure equality.
There is still more... versioning. In the real world, content editors change and update content frequently. Every time a bit of content is saved within Episerver, it is given a new version Id. In Episerver, a bit of contents version number is called the WorkID. In some circumstances you may want to compare the version as well:
In the scenario above the comparison will be false
because the versions are different.
How Do I Compare Content References Within Episerver 8
As of Episerver 8, the best way to compare two content references is to use the standard .Net Equals()
or Compare()
method:
Equals: Determines if the underlying type is the same as the current type:
Compare Compares the values of two ContentReferences
and returns a bool
:
Additionally, there is also an Equals()
overload on the ContentReference
class itself. This works the same way as the CompareToWorkID
that we will cover shortly. To recap, when comparing two content references you should use this code:
How Do I Compare Content References Within Episerver 7
Comparing content in Episerver 7 will involve a different API. You can use CompareToWorkID
to perform ContentReference
comparisons. CompareToWorkID
can be used to compare two items of type ContentReference
while ignoring the WorkID
. When comparing objects of type ContentReference
in V7 this is the approach I recommend:
You are now a ContentReference
Jedi master and you understand the different aspects that uniquely identify content within Episerver. When comparing values you need to take into consideration the Id
, WorkId
and the ProviderName
. Solely comparing the Id
of two bits of contents can result in bugs appearing within your code. Happy Coding 🤘