---
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 document permissions](https://docs.kentico.com/display/K8/Configuring+document+permissions) 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 user is authorized for specified document. The methods checks all content, class, and document 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 documents in MVC applications

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

### Retrieving documents

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

For example, you can:

- Retrieve a single News document from the current site

  ```csharp

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


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

  ```csharp

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

  ```

### Working with retrieved document data

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

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

#### Accessing document form data

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

- In the **Document types** application.
- In the _CONTENT\__ database table.

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

```csharp

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

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

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

```

#### Accessing document metadata

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

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

```csharp

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

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

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

```

## Caching document data in MVC applications

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

The following example implements caching for a retrieved News document:

```csharp

TreeNode document = CacheHelper.Cache(
    cs =>
    {
        // Get the news document
        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 __ 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.
