---
title: MVC code examples
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

## Securing MVC applications

[Kentico page permissions](https://docs.kentico.com/k82/managing-users/configuring-permissions/configuring-page-permissions.md) do not automatically apply to MVC pages. You need to use the [Authorize](http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute\(v=vs.100\).aspx) attribute to secure your MVC application on the controller level.

You can use the Authorize attribute in three ways:

- Allow any authorized user to access a controller.

  ```csharp

  [Authorize]
  public ActionResult ControllerForAllAuthrozizedUsers()
  {
      return View();
  }

  ```
- Allow only specific roles to access a controller.

  ```csharp

  [Authorize(Roles = "Administrators")]
  public ActionResult ControllerForSpecificRoles()
  {
      return View();
  }

  ```
- Allow only specific users to access a controller

  ```csharp

  [Authorize(Users = "Austin", "Jenny")]
  public ActionResult ControllerForSpecificUsers()
  {   
      return View();
  }

  ```

Use the _IsAuthorizedPerDocument()_ method to check if a user is authorized for a specified page. The methods checks all content, class, and page type permissions.

```csharp

DocumentSecurityHelper.IsAuthorizedPerDocument(treeNode, NodePermissionsEnum.Read, true, LocalizationContext.CurrentCulture.CultureCode, MembershipContext.AuthenticatedUser);

```

> **Tip:** **Applying authorize attribute globally**
>
> You can apply the authorize globally, to all controllers. To do that add the authorize attribute to the global filter collection. The following example shows how you can do that in the CMSApp\_MVC project's FilterConfig.cs file.
>
> ```csharp
>
> public static void RegisterGlobalFilters(GlobalFilterCollection filters)
> {
>     // Adds the authorize attribute to the global filter collection
>     Adding filters.Add(new System.Web.Mvc.AuthorizeAttribute());
> }
>
> ```
>
> You can then explicitly whitelist certain controllers. For example, on the registration and logon pages by adding the AllowAnonymous attribute to the specific controllers.

## Working with pages in MVC applications

Use the [page API](https://docs.kentico.com/k82/custom-development/working-with-pages-in-the-api.md) to retrieve and work with page data.

### Retrieving pages

We recommend that you use the _DocumentHelper.DocumentQuery()_ method to retrieve pages. The _DocumentQuery_ method is a plain query for retrieving all pages from the database. You can add restraining conditions to make the query retrieve specific pages.

For example, you can:

- Retrieve a single News page from the current site

  ```csharp

  TreeNode page = DocumentHelper.GetDocuments("CMS.News")
      // Specifies the required page by its node alias path
      .Path(newsNodeAlias)
      // Retrieves pages from the current site only
      .OnCurrentSite()
      // Retrieves only pages currently published on the live site
      .Published()
      // Gets only one record (for optimal database performance)
      .TopN(1)
      // Casts the retrieved page to the TreeNode type
      .FirstObject;


  ```
- Retrieve multiple News pages from the current site

  ```csharp

  InfoDataSet<TreeNode> pages = DocumentHelper.GetDocuments("CMS.News")
      // Specifies the required page by the parent node alias path and defines that only children should be retrieved
      .Path(newsNodeAlias, PathTypeEnum.Children)
      // Retrieves pages from the current site only
      .OnCurrentSite()
      // Retrieves only pages currently published on the live site
      .Published()
      // Casts the retrieved pages to the InfoDataSet<TreeNode> type
      .TypedResult;

  ```

### Working with retrieved page data

You can access the data of a retrieved page using the _Treenode.GetValue()_ method. There are two types of page data that you can access:

- Form data - the data that is editable on a page's _Form_ tab
- Metadata - data like the _page title_ and _page keywords_

#### Accessing page form data

The fields available on a page's Form tab are specific to its Page type. You can see the fields that each page type uses:

- In the **Page types** application.
- In the _CONTENT\_\<document\_type>_ database table.

Page form data is stored in the TreeNode object. You can access the specific fields of a News page in the following way:

```csharp

// Retrieves the page
TreeNode page = DocumentHelper.GetDocuments("CMS.News").Path(newsNodeAlias).FirstObject;

// Accesses the 'NewsTitle' field
page.GetValue("NewsTitle");

// Accesses the 'NewsTest' field
page.GetValue("NewsText");

```

#### Accessing page metadata

Page metadata are stored the same way as Form data (in the TreeNode object). This means that you can use the _GetValue_ method to access page metadata as well.

All the metadata fields you can access are defined in the _CMS\_Document database_ table.

```csharp

// Retrieves the page
TreeNode page = DocumentHelper.GetDocuments("CMS.News").Path(newsNodeAlias).FirstObject;

// Accesses the 'DocumentPageTitle' metadata field
page.GetValue("DocumentPageTitle");

// Accesses the 'DocumentPageKeywords' metadata field
page.GetValue("DocumentPageKeywords");

```

## Caching page data in MVC applications

It is recommended to cache page data when the data is queried from the database frequently. Learn more about [custom caching](https://docs.kentico.com/k82/custom-development/caching-in-custom-code.md) in Kentico.

The following example implements caching for a retrieved News page:

```csharp

TreeNode page = CacheHelper.Cache(
    cs =>
    {
        // Get the news page 
        TreeNode newsDoc = DocumentHelper.GetDocuments("CMS.News").Path(newsNodeAlias).FirstObject;  

        // Setup the cache dependencies only when caching is active
        if ((newsDoc != null) && cs.Cached)
        {
            // Sets the cache dependencies only when caching is active
            string[] nodeDependencies = TreeProvider.GetDependencyCacheKeys(newsDoc, SiteContext.CurrentSiteName);
            cs.CacheDependency = CacheHelper.GetCacheDependency(nodeDependencies);
        }
        return newsDoc;
    },
    new CacheSettings(10, "newsdetail|" +  newsNodeAlias)
);

```

By default, Kentico contains a _NewsController_ example in the _CMSApp\_MVC_ project. Use the caching set up in the controller for reference.

You can also make use of the [MVC OutputCache Attribute](http://msdn.microsoft.com/en-us/library/system.web.mvc.outputcacheattribute\(v=vs.100\).aspx).

## Returning the HTTP 404 error code in MVC applications

You can handle HTTP 404 redirects in the following two ways:

- Redirect user to a page specified in the _\<error statusCode="404" ... />_ element of the web.config file. Use the following method to perform this redirect:

  ```csharp

  return HttpNotFound();

  ```
- Redirect user to a page specified in Kentico's **Settings** **-> Content -> Page not found URL** setting. Use the following method to perform this redirect:

  ```csharp

  URLRewriter.PageNotFound(alwaysRedirect: true);

  ```

## Including CSS in MVC applications

To include a CSS stylesheet in your View files:

1. Add the following using reference:

   ```csharp

   @using CMS.Helpers;

   ```
2. Use the _GetStylesheetUrl()_ method to include the stylesheet:

   ```csharp

   <link href="@CSSHelper.GetStylesheetUrl("CorporateSite")" rel="stylesheet" type="text/css" />

   ```

The View file now uses the specified stylesheet.
