Category Archives: FindPagesWithCriteria

Find Pages containing a certain Content in a ContentArea (UPDATE)


I had some discussions about this blog post and had to check up some things. Accidently I found the IContentRepository.GetReferenceInformationForContent(ContentReference contentLink, bool includeDecendents) (implemented on DataFactory) which runs the Stored Procedure [editDeletePageCheck]. This is normally used to warn an editor about referencing pages when editing och deleting content.

According to the ExpressProfiler it goes to the database each time I run the command so it might be good to keep this in mind.

Here is the new code:

var contents = new List<ContentData>();
var repository = ServiceLocator.Current.GetInstance<IContentRepository>();
IEnumerable references = repository.GetReferencesToContent(contentLink, false);
foreach (ReferenceInformation reference in references)
    ContentReference ownerContentLink = reference.OwnerID;
    CultureInfo ownerLanguage = reference.OwnerLanguage;
    ILanguageSelector selector = new LanguageSelector(ownerLanguage.Name);
    var content = repository.Get<ContentData>(ownerContentLink, selector);

    var contentArea = content["ResponsibleEditors"] as ContentArea;
    if (contentArea != null)
        if (contentArea.ContentFragments.Any(fragment => fragment.ContentLink == contentLink))

While browsing in the tblContentProperty I stumbled upon how a ContentArea is saved in the database.

It’s quite similar to how Dynamic Content is serialized in a XhtmlString:

<div data-classid=”36f4349b-8093-492b-b616-05d8964e4c89″ data-contentguid=”7cef1c69-b345-493c-a60e-ce011fe42c31″ data-contentlink=”35″ data-contentname=”Content Name”>{}</div><div data-classid=”36f4349b-8093-492b-b616-05d8964e4c89″ data-contentguid=”216210e0-f687-4f7a-9bc9-c2a51badab1a” data-contentlink=”701″ data-contentname=”Another Content Name”>{}</div>

In my example I have a Page Type called EditorPage presenting all persons in the staff who can be responsible to the web sites articles.

To present an articles responsible editor I have added a ContentArea where the editor simply drops Editor Pages.

On the Editor Page I want to list all the article where the Editor is connected.

So all I have to do to find pages that have a specific Content (for example Page or Block) referenced in a ContentArea is this:

string id = ID-TO-YOUR-CONTENT;
PropertyCriteriaCollection criterias = new PropertyCriteriaCollection
    new PropertyCriteria
            Condition = CompareCondition.Contained,
            Name = "ResponsibleEditors",
            Required = true,
            Type = PropertyDataType.String,
            Value = string.Format("data-contentlink=\"{0}\"", id)
IPageCriteriaQueryService queryService = ServiceLocator.Current.GetInstance<IPageCriteriaQueryService>();
PageDataCollection pages = queryService.FindPagesWithCriteria(ContentReference.StartPage, criterias);

You can also use the content GUID and use this as Value: string.Format(“data-contentguid=\”{0}\””, guid)

As usual, if you want to use FindPagesWithCriteria, remember to put a cache on it since it can be quite heavy on the database.

The quest of FindPagesWithCriteria with a Block Property in EPiServer 7 CMS

There are several exciting things with the new Blocks in EPiServer 7 CMS. One of the most convenient things when you need to add a group of data to a page type, for example an image + alternative text or an url + clickable text or maybe a group of SEO data such as title, description and keywords.

Note that this article does not include how Global Blocks are saved. I have only focused on Blocks that are added as Properties on a Content Type.

I have create a sample Page Type TestPage containing 2 sets of the block TestBlock which itself only contains the string Property TestValue. TestBlock1 contains the value “abc” and TestBlock2 contains the value “def”.

When I check the database structure I can find these traces of ContentTypes, Properties and values. I have marked the recurring values to mark how the relations are set between all  tables.

Database Structure


pkID ContentTypeGUID ModelType Name ContentType
23 34CC512A-5680-47CA-86EF-80F38A688F40 EPiServer.Templates.Alloy.Models.Blocks.TestBlock, EPiServer.Templates.Alloy, Version=, Culture=neutral, PublicKeyToken=null TestBlock 1
24 64E21501-096A-4983-AE87-03D274FE98B2 EPiServer.Templates.Alloy.Models.Pages.TestPage, EPiServer.Templates.Alloy, Version=, Culture=neutral, PublicKeyToken=null TestPage 0


pkID Property Name TypeName AssemblyName fkContentTypeGUID
1010 12 TestBlock NULL NULL 34CC512A-5680-47CA-86EF-80F38A688F40

Where the column fkContentTypeGUID is null on PropertyDefinitionTypes that are not connected to a ContentType


pkID fkContentTypeID fkPropertyDefinitionTypeID Name Property
133 23 7 TestValue 7
134 24 1010 TestBlock1 12
135 24 1010 TestBlock2 12

Where fkPropertyDefinitionTypeID 7 mean it’s a normal string and strangely 12 is a XhtmlString but I guess it has something to do with rendering. *adding to future blogs list*


pkID fkPropertyDefinitionID fkContentID fkLanguageBranchID ScopeName guid LongString LongStringLength
1628 133 183 1 .134.133. 1C2D6A8D-6973-4E36-9BC9-9E655506795C abc 6
1628 133 183 1 .135.133. 1C2D6A8D-6973-4E36-9BC9-9E655506795C def 6

I have created a Page of TestPage. The page have Id 183, it didn’t feel necessary to add that table to this chart but as you can see, the values of TestBlock1 and TestBlock2 have a fkContentID that referers to the PageData it is stored on.

The column ScopeName is a relational path that connects the Name property to the TestBlock Block named TestBlock1.

Find Pages based on this?

The datastructure for Blocks in tblContrentProperty are quite flat. Therefore I can find my Test Page by creating a FindPagesWithCriteria:

IPageCriteriaQueryService repository = ServiceLocator.Current.GetInstance();

PropertyCriteriaCollection criterias = new PropertyCriteriaCollection
    new PropertyCriteria
        Condition = CompareCondition.Equal,
        Required = true,
        Name = "TestValue",
        Type = PropertyDataType.String,
        Value = "abc"
PageDataCollection result = repository.FindPagesWithCriteria(ContentReference.RootPage, criterias);

FindPagesWithCriteria sends queries to a couple of Stored Procedures in the database and checks among the tables whether the Pages have a Property with the given name and  if the Property value fits the criteria.

And what is the result?

Unfortunately since there is no way to define that I only want to search for a page where TestBlock1 have a TestValue with value “abc”, I will receive ALL pages that have a Property called TestValue with a value of “abc” no matter if they are saved on a block or directly on the page.

This really sounds like a job for EPiServer Find but if you don’t have it installed, FindPagesWithCriteria can be quite good at times except for the disadvantages of many queries to the database and its cumbersome API.

Though the advantages is its stability and being straightforward. Remember to not add too many criterion and try to Cache-smart if you using it

What I can find there is no good way to change the behaviour of FindPagesWithCriteria without copying quite alot of the existing logic or rewriting the existing Stores Procedures.