MVC code examples

Securing MVC applications

Kentico document permissions do not automatically apply to MVC pages. You need to use the Authorize 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.

    
    
    
      [Authorize]
      public ActionResult ControllerForAllAuthrozizedUsers()
      {
          return View();
      }
    
    
      
  • Allow only specific roles to access a controller.

    
    
    
      [Authorize(Roles = "Administrators")]
      public ActionResult ControllerForSpecificRoles()
      {
          return View();
      }
    
    
      
  • Allow only specific users to access a controller

    
    
    
      [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.




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


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.




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 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

    
    
    
      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

    
    
    
      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_<document_type> 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:




// 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.




// 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 in Kentico.

The following example implements caching for a retrieved News document:




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.

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:

    
    
    
      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:

    
    
    
      URLRewriter.PageNotFound(alwaysRedirect: true);
    
    
      

Including CSS in MVC applications

To include a CSS stylesheet in your View files:

  1. Add the following using reference:

    
    
    
     @using CMS.Helpers;
    
    
     
  2. Use the GetStylesheetUrl() method to include the stylesheet:

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

The View file now uses the specified stylesheet.