A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More


Sep 22, 2011
  4623
(5 votes)

FindPagesWithCriteriaContext – Just because I can

Introduction

I have a large list of things within the .Net world in which I would like to enrich my knowledge with.  For a while now custom Linq query providers and expression trees have been one of the things I wanted to learn more about.

For the last few days during my daily commute I have been knocking together a query provider which will sit on top of FindPagesWithCriteria API.

Why would I want to do this you may ask? Well, just because I can and it also enriches my knowledge Winking smile

Last year Johan Olofsson blogged about Linq to PageData, I personally have not got round to playing with this but it does look very useful.

FindPagesWithCriteriaContext is no replacement for what Johan has previously done but I personally think if you do use FindPagesWithCriteria in your everyday job, it’s a nice little wrapper on top of the FindPagesWithCriteria API.

The code has been tested at a very rudimentary level, but there could well be issues.  Also, QueryBuilder’s and expression trees are new to me and although the code works I possibly could have gone about things in a better way and possibly areas of code could be optimized.  But, hey this was a learning exercise with possibly something slightly useful coming out of it.  Well, I think so anyway Smile with tongue out

Installation

Download the FindPagesWithCriteriaContext.cs class from here and add it to your project file.

The code has a dependency on PageTypeBuilder.  This is because some classes within PTB are used to resolve PageTypeID’s and property data types.


Usage

There are two classes that can be used for the Linq based FindPagesWithCriteria queries these are FindPagesWithCriteriaContext and FindAllPagesWithCritieraContext

These classes have constructors that accept the usual FindPagesWithCriteria method call parameters.

The following operators are supported in the Linq syntax:

  • ==
  • !=
  • >
  • >=
  • <
  • <=
  • &&
  • ||
  • string.StartsWith
  • string.Contains

The query provider only has support for where and order by clauses.

An example Linq query is below:

  1: CategoryList categoryList = new CategoryList(new[] { Category.Find("News").ID, Category.Find("Product").ID });
  2: 
  3: var query3 = from page in new FindPagesWithCriteriaContext<PageTypeTwo>(PageReference.StartPage)
  4:              where page.VisibleInMenu &&
  5:              page.Category == categoryList &&
  6:              page.Number > 100 &&
  7:              page.PageName.StartsWith("P") &&
  8:              page.PageName.Contains("a") &&
  9:              page.NullableProperty == null
 10:              orderby page.PageName descending
 11:              select page;
 12: 
 13: var pages3 = query3.ToList();

When the Linq query is created the relevant PropertyCriteria the Linq query is converted to will be written to the output window in debug mode.

The criteria for the query above looks like the following:

FindPagesWithCriteriaContext criteria:

Critieria 1:
Name: PageTypeID
Condition: Equal
Required: True
Type: PageType
Value: 34
IsNull: False

Critieria 2:
Name: PageVisibleInMenu
Condition: Equal
Required: True
Type: Boolean
Value: True
IsNull: False

Critieria 3:
Name: PageCategory
Condition: Equal
Required: False
Type: Category
Value: News
IsNull: False

Critieria 4:
Name: PageCategory
Condition: Equal
Required: False
Type: Category
Value: Product
IsNull: False

Critieria 5:
Name: Number
Condition: GreaterThan
Required: True
Type: Number
Value: 100
IsNull: False

Critieria 6:
Name: PageName
Condition: StartsWith
Required: True
Type: String
Value: P
IsNull: False

Critieria 7:
Name: PageName
Condition: Contained
Required: True
Type: String
Value: a
IsNull: False

Critieria 8:
Name: NullableProperty
Condition: Equal
Required: True
Type: Boolean
Value:
IsNull: True

When the query is then executed, depending on whether you are using the FindPagesWithCriteriaContext or the FindAllPagesWithCriteriaContext classes will determine whether access rights and permissions are ignored or not when retrieving PageData objects.

Additional Information

When creating an instance of the Context classes above you can specify a TypeParam which must inherit or be of type PageData.  If you provide a PageTypeBuilder class then the pages returned from the query call will be converted to the PageTypeBuilder type.

When building up the Linq query, inline values, variables and method calls can be used for the property values being compared to.


Disclaimer

I better protected myself just in case anybody wants to give it a go and use it Smile

I have done some rudimentary testing on the query provider and it seems to be working as I would like but there could well be bugs that I have not found Sad smile

So, in short use at your own risk and I would recommend when creating your own queries you should verify the PropertyCriteria the query has been translated to in the Output window.
 

Feedback

Feedback as always is greatly received.  If there are bugs/issues please feel free to email or twitter me @croweman and I will do my best to resolve them.  Thanks for reading Smile

Sep 22, 2011

Comments

robert.andersson@nansen.se
robert.andersson@nansen.se Sep 22, 2011 02:20 PM

Well done! Gonna try this out asap :)

smithsson68@gmail.com
smithsson68@gmail.com Sep 22, 2011 03:08 PM

Really nice Lee.

Kjetil Simensen
Kjetil Simensen Oct 4, 2011 08:25 AM

Very cool! will definitively try it out.

Please login to comment.
Latest blogs
Looking back at Optimizely in 2025

Explore Optimizely's architectural shift in 2025, which removed coordination cost through a unified execution loop. Learn how agentic Opal AI and...

Andy Blyth | Dec 17, 2025 |

Cleaning Up Content Graph Webhooks in PaaS CMS: Scheduled Job

The Problem Bit of a niche issue, but we are building a headless solution where the presentation layer is hosted on Netlify, when in a regular...

Minesh Shah (Netcel) | Dec 17, 2025

A day in the life of an Optimizely OMVP - OptiGraphExtensions v2.0: Enhanced Search Control with Language Support and Synonym Slots

Supercharge your Optimizely Graph search experience with powerful new features for multilingual sites and fine-grained search tuning. As search...

Graham Carr | Dec 16, 2025

A day in the life of an Optimizely OMVP - Optimizely Opal: Specialized Agents, Workflows, and Tools Explained

The AI landscape in digital experience platforms has shifted dramatically. At Opticon 2025, Optimizely unveiled the next evolution of Optimizely Op...

Graham Carr | Dec 16, 2025

Optimizely CMS - Learning by Doing: EP09 - Create Hero, Breadcrumb's and Integrate SEO : Demo

  Episode 9  is Live!! The latest installment of my  Learning by Doing: Build Series  on  Optimizely Episode 9 CMS 12  is now available on YouTube!...

Ratish | Dec 15, 2025 |

Building simple Opal tools for product search and content creation

Optimizely Opal tools make it easy for AI agents to call your APIs – in this post we’ll build a small ASP.NET host that exposes two of them: one fo...

Pär Wissmark | Dec 13, 2025 |