Retrieve page content

Web page content is stored in the database and edited through the administration interface using the content tree in website channel applications.

Xperience by Kentico provides the ContentRetriever API as the primary and recommended approach for retrieving page content. This API simplifies content retrieval with built-in caching, context awareness, and optimized performance.

The ContentRetriever API works with:

  • Generated content type classes – classes generated by the system that allow you to work with content type fields using strongly-typed objects. These classes also allow access to all general page data (page title, ID, GUID, creation date, publish date, etc.).
  • Custom data transfer objects (advanced use case) – using custom DTOs grants you control over the mapping logic. See Custom model mapping.

You can also use:

The implementation and complexity of the retrieval and management code depend on your preferences and project requirements, and can range from simple method calls within controller actions to custom solutions utilizing repository and service patterns. Install the sample Dancing Goat project to view a reference implementation.

Retrieve page data

To retrieve web page content, use the IContentRetriever service from the Kentico.Content.Web.Mvc namespace:

The service provides built-in caching, channel context awareness, and optimal retrieval performance. You can use the IContentRetriever to Retrieve the current page, Retrieve pages of a single content type, and more. See Reference - ContentRetriever API for a list of all available methods.

C#
Sample page retrieval


// Services obtained via dependency injection
private readonly IContentRetriever contentRetriever;

public async Task PageRetrieval()
{
    // Retrieves pages of the 'ArticlePage' content type from the /Articles section
    var pages = await contentRetriever.RetrievePages<ArticlePage>(
        new RetrievePagesParameters 
        { 
            PathMatch = PathMatch.Children("/Articles"),
        });

    // Displays the page data
    foreach(var page in pages)
    {
        Console.WriteLine(page.ArticleTitle);
        Console.WriteLine(page.ArticlePageSummary);
    }
}

For scenarios requiring advanced query customization, you can use the content item query API:

  • ContentItemQueryBuilder class with the ForWebsite query parametrization method – to create and parametrize custom queries specifically for retrieving website data.
  • IContentQueryExecutor interface and its GetMappedWebPageResult method – to execute custom queries and map the results to model classes.

Retrieve multilingual page data

To retrieve web page content in a specific language using the IContentRetriever, specify the desired language when calling the retrieval methods by providing them with a RetrievePagesParameters object with the LanguageName property set. If you omit the language, the method will return results in the primary language of the website channel.

C#
Sample multilingual page retrieval


// Retrieves pages in the Spanish language
var pages = await contentRetriever.RetrievePages<ArticlePage>(
    new RetrievePagesParameters { LanguageName = "es" }
);

Pages in fallback language

If the desired language variant of a page doesn’t exist, the query returns the page data in the fallback language, if fallbacks are configured and unless the UseLanguageFallbacks property of the RetrievePagesParameters object is explicitly set as false.

Filter pages based on content tree structure

You can set the query to only include pages from a certain section of the content tree or omit pages from a section using the PathMatch property of the RetrievePagesParameters object. PathMatch expressions can be combined to more accurately specify what pages are included in the query.

  • Single – only retrieves a single page that corresponds to the specified tree path.
    • E.g., PathMatch.Single(path: "/Articles/Coffee_processing_techniques")
  • Children – recursively retrieves all children of a specified parent page, excluding the parent page from the query. You can also specify a nesting level to limit the depth of recursion.
    • E.g., PathMatch.Children(path: "/Articles", nestingLevel: 3)
  • SkipChildren – recursively exclude all children of a specified parent page from the query, except for the parent page. You can also specify a nesting level to limit the depth of recursion.
    • E.g., PathMatch.SkipChildren(path: "/Articles/Coffee", nestingLevel: 3)
  • Section – recursively retrieves all children of a specified parent page, including the parent page in the query. You can also specify a nesting level to limit the depth of recursion.
    • E.g., PathMatch.Section(path: "/Articles", nestingLevel: 3)
  • SkipSection – recursively exclude all children and the specified parent page from the query. You can also specify a nesting level to limit the depth of recursion.
    • E.g., PathMatch.SkipSection(path: "Articles/Coffee", nestingLevel: 3)

Combine PathMatch expressions

If you need to combine multiple PathMatch expressions, use content item query and pass an array as the argument to the ForWebsite method.

C#
Example - Combine PathMatch expressions


var builder = new ContentItemQueryBuilder()
                    .ForContentType(
                        "My.ArticlePage",
                        config => config
                            .ForWebsite(
                                websiteChannelName: "MyWebsiteChannel",
                                pathMatches: new PathMatch[]{
                                    PathMatch.Children("/Articles"),
                                    PathMatch.SkipSection("/Articles/Coffee_processing_techniques")
                                }
                            )
                    );

Filter pages based on tags

You can limit the retrieval to only retrieve pages with the specified tags using the additionalQueryConfiguration parameter with the WhereContainsTags method:

C#
Example - Filter by tags


// Retrieves pages that contain both "coffee" and "processing" tags
var pages = await contentRetriever.RetrievePages<ArticlePage>(
    new RetrievePagesParameters 
    { 
        PathMatch = PathMatch.Children("/Articles") 
    },
    query => query.WhereContainsTags("coffee", "processing"),
    new RetrievalCacheSettings(cacheItemNameSuffix:
                                    $"{nameof(WhereParameters.WhereContainsTags)}|coffee|processing"));

See Retrieve content items for more information on working with tags.

Page security configuration

Pages can be secured to allow access only to authenticated users. By default, the IContentRetriever doesn’t include secured pages in the query results. You can change this behavior by setting the IncludeSecuredItems property of the RetrievePagesParameters object to true.

C#
Example - Include secured pages


var pages = await contentRetriever.RetrievePages<ArticlePage>(
    new RetrievePagesParameters 
    { 
        IncludeSecuredItems = true // Include secured pages in the results
    });

The secured state of a retrieved page is indicated by its page.SystemFields.ContentItemIsSecured property. You can use this property to display information to visitors accordingly.

For example, you can pass the page’s ContentItemIsSecured property to a model and display an appropriate message to visitors. 

cshtml
Reflect page security in views


// In this case, the 'ContentItemIsSecured' is mapped to the 'IsSecured' property of this view model 
@if (model.IsSecured && !User.Identity.IsAuthenticated)
{
    <p>
        Sign in to access this page
    </p>
}

An alternative popular practice is to display a blurred teaser image overlaid with a lock to indicate elevated permission requirements.

You can check whether the current ClaimsPrincipal is authenticated via User.Identity.IsAuthenticated. If unauthenticated visitors attempt to access a secured page, the server returns HTTP 403 Forbidden. ASP.NET Identity can be configured to automatically redirect such requests to another location on the website (typically a registration or sign in page) via AccessDeniedPath.

C#
Program.cs


builder.Services.ConfigureApplicationCookie(options =>
{
    // Responses that would otherwise return 403 are instead redirected to <domain>/account/signin
    options.AccessDeniedPath = new PathString("/account/signin");
});

Work with retrieved page data

You can access various types of data from retrieved page objects:

  • Content type fields – the data that is editable in a page’s Content view mode. The set of available fields is configurable via the field editor.
  • System fields – available under the SystemFields property of the retrieved page objects. Access WebPage* fields for web page data and ContentItem* for data of the underlying content item.
  • Page URL – see Retrieve page URLs.
C#
Access page data


// Retrieves a page
var page = await contentRetriever.RetrievePage<ArticlePage>();

// Accesses the ID of the parent
var parentId = page.SystemFields.WebPageItemParentID;

// Accesses the code name of the page object
var pageName = page.SystemFields.WebPageItemName;

Access page field data

The fields available in a page’s Content view mode are specific to its content type. You can see the fields that each content type uses:

  • In Content types (application) → edit a content type → Fields tab
  • In the corresponding <namespace>_<content_type_name> database table

You can access specific fields of a content type directly using strongly typed properties when using generated content type classes:

C#
Access content type fields


// Retrieves a page
var page = await contentRetriever.RetrievePage<ArticlePage>();

// Accesses the 'Text' field of the page
var pageText = page.ArticlePageText;

// Accesses the 'Teaser' field of the page
var pageImage = page.ArticlePageTeaser.FirstOrDefault();

Resolving HTML tags and relative URLs

Fields which are populated by the Rich text editor form component may contain HTML tags and relative links. To ensure that the content is displayed correctly when rendered in Razor views, use the Html.Raw method, which disables HTML encoding for the values.

cshtml


@Html.Raw(Model.<RichTextFieldProperty>)

Automatic URL resolving

The system provides page output filtering functionality that automatically resolves all virtual relative URLs to their absolute form. This filter ensures that links added by content editors into page content work correctly, even if you do not explicitly handle URL resolving in your code.

Date and time fields

DateTime fields and system properties of retrieved pages always have values in the time zone of the server where the application is running. If you wish to display values in a different time zone (e.g., in a website visitor’s local time), perform a time conversion using the standard .NET API.

Access context of the current request

Xperience by Kentico provides interfaces that help you access information about the current context.

Access context of the current channel

To retrieve information about the website channel context of the current request, use an instance of the IWebsiteChannelContext interface (e.g., obtained via dependency injection) from the CMS.Websites.Routing namespace.

Access the following properties:

  • WebsiteChannelID – the ID of the current website channel.
  • WebsiteChannelName – code name of the current website channel.
  • IsPreview – a boolean value that, if true, signifies whether the current request is made in preview (Page Builder or the preview mode in a website channel application).

Access current preferred language

To retrieve the preferred language of the current request, use the Get method of the IPreferredLanguageRetriever interface (e.g., obtained via dependency injection).

Note that the preferred language of the request can be different from the actual language of the retrieved content. For example, if language variant of a page does not exist in the preferred language, fallback language variant is retrieved.

C#
Retrieve currently preferred language


// An instance of  IPreferredLanguageRetriever (e.g., obtained via dependency injection)
private readonly IPreferredLanguageRetriever preferredLanguageRetriever;

// Retrieves the code name of the preferred language
string languageName = preferredLanguageRetriever.Get();

Retrieve pages for preview

The ContentRetriever API automatically handles preview context, retrieving the appropriate page versions based on the current request context:

  • For the live site, retrieves published versions according to security claims
  • For preview and builders, retrieves the latest available version regardless of workflow state or security

You can use the IsForPreview parameter of the RetrievePagesParameters object to force either only preview or only live data.

C#
Always retrieve latest data


var pages = await contentRetriever.RetrievePages<ArticlePage>(
    new RetrievePagesParameters 
    { 
        IsForPreview = true // Force retrieval of preview data
    });

Add preview context to URLs

You may encounter problems in Preview mode on pages that send requests to a custom API endpoint, which uses IWebsiteChannelContext to access the current channel in its implementation. To ensure that such endpoints work correctly in Preview mode, you need to add preview context data to the endpoint URL.

cshtml
Example


@using Kentico.Content.Web.Mvc

const endpointUrl = @Url.Kentico().ApplyPreviewContext("url");

The ApplyPreviewContext Razor extension method adds various parameters to the endpoint URL, which ensure that IWebsiteChannelContext is able to identify the channel, where the previewed page belongs, regardless of the domain used to access the admin UI.

Retrieve folders

To retrieve the folders from the content tree of a website channel (e.g., to create a page under the folder), use the Retrieve method of the IWebPageFolderRetriever interface (e.g., obtained via dependency injection).

C#
Retrieve folders


// Services obtained via dependency injection
private readonly IWebPageFolderRetriever folderRetriever;
private readonly IWebsiteChannelContext channelContext;

// Retrieves a folder from the specified path
WebPageFolder folder = (await folderRetriever.Retrieve(channelContext.WebsiteChannelName, PathMatch.Children("/Articles"))).FirstOrDefault();

// Use the WebPageFolder object to access information about the folder
int id = folder.ContentItemID;