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:
- Parameter objects for configuring retrieval behavior (language, caching, security, etc.)
- Optional query configuration for advanced scenarios
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.
// 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:
ContentItemQueryBuilderclass with theForWebsitequery parametrization method – to create and parametrize custom queries specifically for retrieving website data.IContentQueryExecutorinterface and itsGetMappedWebPageResultmethod – 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.
// 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")
- E.g.,
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)
- E.g.,
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)
- E.g.,
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)
- E.g.,
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)
- E.g.,
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.
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 Where method and its WhereContainsTags condition:
// Retrieves pages that contain both "coffee" and "processing" tags
var pages = await contentRetriever.RetrievePages<ArticlePage>(
new RetrievePagesParameters
{
PathMatch = PathMatch.Children("/Articles")
},
query => query.Where(where => where.WhereContainsTags("coffee", "processing")),
new RetrievalCacheSettings(cacheItemNameSuffix:
$"{nameof(WhereParameters.Where)}|{nameof(WhereParameters.WhereContainsTags)}|coffee|processing"));
See Retrieve content items for more information on working with tags.
Page security configuration
Pages can be secured using a three-tier content access model. Depending on the access settings configured for a page, the system determines whether the visitor is allowed to view the content:
- Public – the page is accessible to all visitors without restrictions.
- Secured – the page requires the visitor to be an authenticated member.
- Secured with member roles – the page requires the visitor to be an authenticated member who belongs to at least one of the designated member roles.
By default, the IContentRetriever does not include secured pages in the query results. You can change this behavior by setting the IncludeSecuredItems property of the RetrievePagesParameters object to true:
var pages = await contentRetriever.RetrievePages<ArticlePage>(
new RetrievePagesParameters
{
IncludeSecuredItems = true // Includes secured pages in the results
});
Check access with HasAccess
The HasAccess extension method on IContentItemFieldsSource is the recommended way to check whether a visitor has access to a retrieved content item. The method evaluates the page’s security state, the visitor’s authentication status, and the visitor’s member role assignments in a single call:
using Kentico.Content.Web.Mvc;
...
// Retrieves secured pages
var pages = await contentRetriever.RetrievePages<ArticlePage>(
new RetrievePagesParameters
{
IncludeSecuredItems = true
});
foreach (var page in pages)
{
// Checks if the current visitor has access to the page
bool canAccess = page.HasAccess(HttpContext.User);
}
HasAccess returns true if:
- The page is not secured (public).
- The page is secured and the visitor is authenticated (when no specific member roles are required).
- The page is secured with member roles and the visitor is authenticated and belongs to at least one of the required roles.
You can use the result to conditionally display content in Razor views:
@using Kentico.Content.Web.Mvc
@if (!Model.Page.HasAccess(User))
{
<p>
Sign in or upgrade your membership to access this page.
</p>
}
Additional security properties
The secured state of a retrieved page is available through page.SystemFields.ContentItemIsSecured. To see which member roles are required for a secured page, access page.SystemFields.ContentItemRequiredMemberRoleNames, which returns an IReadOnlyCollection<string> of role code names. For unsecured pages, the collection is empty.
Authentication and authorization responses
When a visitor requests a secured page that they are not allowed to view, the system distinguishes between two scenarios:
- Not authenticated (HTTP 401) – the visitor is not signed in. The system issues a challenge that redirects the visitor to the sign-in page.
- Forbidden (HTTP 403) – the visitor is signed in but does not have the required member role. The system redirects the visitor to the access denied page.
You can configure ASP.NET Identity cookie authentication to handle both scenarios. Set LoginPath for unauthenticated redirects and AccessDeniedPath for insufficient-role redirects:
builder.Services.ConfigureApplicationCookie(options =>
{
// Redirects unauthenticated visitors to the sign-in page
options.LoginPath = new PathString("/account/signin");
// Redirects authenticated visitors without the required role to the access denied page
options.AccessDeniedPath = new PathString("/account/access-denied");
});
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
SystemFieldsproperty of the retrieved page objects. AccessWebPage*fields for web page data andContentItem*for data of the underlying content item. - Page URL – see Retrieve page URLs.
// Retrieves a page
var page = await contentRetriever.RetrievePages<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:
// Retrieves a page
var page = await contentRetriever.RetrievePages<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.
@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, iftrue, 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.
// 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.
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.
@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).
// 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;