We have an extension method that determines whether a LinkItem is referring to an internal object, and another method that attempts to retreive the ContentReference for that LinkItem, as below:
/// Checks whether a LinkItem refers to an internal object.
public static bool IsInteral(this LinkItem linkItem)
if (linkItem == null)
throw new ArgumentNullException("linkItem", "LinkItem cannot be null");
return ToContentReference(linkItem) != ContentReference.EmptyReference || linkItem.Href.StartsWith("~/link", StringComparison.InvariantCultureIgnoreCase);
/// Returns a ContentReference for a LinkItem.
public static ContentReference ToContentReference(this LinkItem linkItem)
if (linkItem == null)
var urlBuilder = new UrlBuilder(linkItem.Href);
You'll notice in the IsInternal method there is a call to the StartsWith extension - that's because we like to think of references to deleted content as still being internal (it was internal at one point) - that way we can filter using a set of standard content filters we use. Plus, it feels pretty safe as it is impossible to enter "~/link/guid.aspx" into one of the external page/email address options in a linkitem collection - they are always appended with a protocol.
The problem we're experiencing is that unfortunately the ToContentReference method doesnt work when a LinkItem refers to a page that has no template. I get why - the SoftLinks reposittory only stores links to internal content that actually has a template and therefore a valid Url - that seems logical. However when a page without a template is stored within a LinkItemCollection the url returned for that item is /episerver/CMS/edit/PreviewContainerPage.aspx which gives us absolutely no way of retreiving the ContentReference for that item - or none that I can think of anyway.
I realise that some people will say pages without a template shouldn't exist in a LinkItemCollection but whilst it's possible via the UI our codebase should at least cover all scenarios.
Can anyone help with this little conundrum?
What are your purpose of the linkitemcollection? If it's simply referencing nodes in your structure I would suggest a content area
Thanks for your response.
Usually we use the LinkItemCollection for modules such as related links, related documents etc. These could be internal or external documents hence the LinkItemCollection really is the perfect property for the job.
If a LinkItemCollection contains a linkitem referencing deleted content the url for that link item is an unresolved soft link I.e. ~/link/guid.aspx so I had thought it would be the same for pages without a template but it's just not the case. It's a shame because regardless of whether the referenced page has a template or not it is still referring to a piece of content stored in EPiServer so it would seem only logical that there's a way or of resolving the content reference.