Looking for a little assistance here as I'm trying to learn the ropes with EpiServer.
I'm trying to put together some logic to get a list of all our custom blocks and list out every page these blocks are used on. Fortunately all our custom blocks inherit an abstract class called GlobalBlockData.
I've made a good start thus far & been able to get a list of all the blocks in a List of ContentUsage but at this point im stuck.
Strangely the usages collection (List<ContentUsage>) seems to have the same entry a few times and I can't work out why - I know that a block only exists twice but I see 11 entries - This is only set up in one language so why am I seeing multiples?
From this point I now need to get the absoloute URLs for the apges these are used on.
Is anyone able to help please?
var _contentTypeRepo = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
var _contentModelUsage = ServiceLocator.Current.GetInstance<IContentModelUsage>();
var _linkRepo = ServiceLocator.Current.GetInstance<IContentSoftLinkRepository>();
var _contentRepo = ServiceLocator.Current.GetInstance<IContentRepository>();
//Get all custom blocks which inherit the abstract class GlobalBlockDataIEnumerable<GlobalBlockData> exporters = typeof(GlobalBlockData)
.Where(t => t.IsSubclassOf(typeof(GlobalBlockData)) && !t.IsAbstract)
.Select(t => (GlobalBlockData)Activator.CreateInstance(t));
foreach (GlobalBlockData block in exporters)
Type type = block.GetType();
ContentType contentType = _contentTypeRepo.Load(type);
if (! _contentModelUsage.IsContentTypeUsed(contentType))
//Block Not currently in use
table.Rows.Add(contentType.Name, "NOT IN USE", "NOT IN USE");
//Block In use....
IList<ContentUsage> usages =
foreach (ContentUsage item in usages)
IEnumerable<ReferenceInformation> references =
// THIS IS WHERE IM STUCK
You can try this-
When you view a block in Episerver edit mode, you will see this information.
Try digging around with DotPeek, or ILSpy, and see what Episerver does. My guess is that it involves IContentSoftLinkRepository.
You're almost there :) The Stack Overflow link should help you using the IContentSoftLinkRepository. You also need to get distinct model usage since content versions counts against usage. Something like this:
//// var _urlResolver = ServiceLocator.Current.GetInstance<IUrlResolver>();
// Use distinct since usage also counts against content versions
var usages = _contentModelUsage.ListContentOfContentType(contentType)
.Select(x => x.ContentLink.ToReferenceWithoutVersion())
foreach (var usage in usages)
// Find all pages where the block is used
var references = _linkRepo.Load(usage, reverse: true)
.Where(x => x.SoftLinkType == ReferenceType.PageLinkReference && ContentReference.IsNullOrEmpty(x.OwnerContentLink) == false)
.Select(x => x.OwnerContentLink);
foreach (var reference in references)
var externalUrl = _urlResolver.GetUrl(
ContextMode = ContextMode.Default,
ForceAbsolute = true }
Thanks for the help. This gives me some results but weirdly some usages return no reference & some references dont return a URL.
Any ideas why this might be?
I was guessing perhaps its because the block is nested within another block etc...
not sure if that's relevant for you but soft link indexer only indexes published content