Try our conversational search powered by Generative AI!

Loading...
Area: Optimizely CMS
Applies to versions: 10-11
Other versions:
ARCHIVED This content is retired and no longer maintained. See the version selector for other versions of this topic.

View models and partial views

Recommended reading 

This topic introduces the concept of views, view models and partial views, and provides some examples of how to use these when developing Episerver CMS websites using MVC. Refer to the MVC framework documentation for more details on how to work with views and view models.

How it works

In MVC, a template corresponds to a controller and a view, where the controller selects the view to display. The view contains the actual HTML template with embedded code, generating content sent to the client.

Views are .cshtml files stored by default in the Views folder. Action-specific views, partial views, and layouts are used to reduce repetition. By convention in MVC, the default layout is named _Layout.cshtml located in the Views/Shared folder. See Views (Microsoft) for more information.

To avoid repetition, you can create a base controller to be used by the page base class and inherited by other controllers. You can also create view models and partial views to make your views more flexible, for example when creating menus and other navigation components.

View models

There are several ways of passing data to views. A view model is useful if you want to pass data beyond PageData objects into your views. You can define a model type in the view, and pass an instance of this type to the view from the action.

In this example we use an interface IPageViewModel and a DefaultPageViewModel based on a SitePageData base class.

Example: Controller for a Standard page based on a PageControllerBase, using a DefaultPageViewModel.

namespace MyEPiServerSite.Controllers
{
    public class StandardPageController : PageControllerBase<StandardPage>
    {
        public ActionResult Index(StandardPage currentPage)
        {
            /* Implementation of action. You can create your own view model class that you pass to the view or
             * you can pass the page type for simpler templates */

            DefaultPageViewModel<StandardPage> model = new DefaultPageViewModel<StandardPage>(currentPage);
            return View(model);
        }
    }
}
Example: The DefaultPageViewModel with the IPageViewModel interface, and a ContentExtensions class used for rendering a left navigation section.
namespace MyEpiserverSite.Models.ViewModels
{
    public class DefaultPageViewModel<T> : IPageViewModel<T> where T : SitePageData
    {
        public DefaultPageViewModel(T currentPage)
        {
            CurrentPage = currentPage;
            Section = ContentExtensions.GetSection(currentPage.ContentLink);
        }

        public T CurrentPage { get; set; }
        public IContent Section { get; set; }
    }
}
PropertyFor is one of many Episerver Html helpers. PropertyFor is frequently used for displaying markup for properties, and will automatically enable on-page editing of the property when used.
  
Example: View for the Standard page, displaying the left navigation, with page name and main body properties.
@using MyEPiServerSite.Models.Pages
@model MyEPiServerSite.Models.ViewModels.DefaultPageViewModel<StandardPage>

@{
    Layout = "~/Views/Shared/Layouts/_LeftNavigation.cshtml";
}

<h1>
    @Html.PropertyFor(x => x.CurrentPage.PageName)
</h1>
<div class="row">
    <div class="span8 clearfix" >
        @Html.PropertyFor(x => x.CurrentPage.MainBody)
    </div>
</div>

Partial views

A partial view is a view that is rendered within another view. The HTML output generated is rendered into the calling view. Common layout elements are usually defined in one view, and specific non-reusable layout elements are defined using partial views. See Partial views (Microsoft) for more information.

Example: A partial view for rendering a simple top navigation listing subpages to the start page, with links to each page. 

@using EPiServer.Core

@{ 
    var cr = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<EPiServer.IContentRepository>();
    var childPages = cr.GetChildren<PageData>(ContentReference.StartPage);
}

{
<b>@Html.PageLink(ContentReference.StartPage)</b>
@foreach (var page in childPages)
{
    <b>
        @Html.PageLink(page)
    </b>
}

Example: The "Navigation" partial view added to the shared _Layout view, resulting in a top menu display for all pages.

@using EPiServer.Framework.Web.Mvc.Html
@using EPiServer.Core
@using MyEpiserverSite.Models.Pages
@using MyEpiserverSite.Models.ViewModels;

@model IPageViewModel<SitePageData>

<!DOCTYPE html>

<html>
<head>
    <title>@Model.CurrentPage.Name</title>
    <link rel="stylesheet" href=...)"></script>
</head>
<body>
    @Html.RenderEPiServerQuickNavigator()

    @Html.FullRefreshPropertiesMetaData()
    <div class="container">
        <div class="row">
            <div id="header">
                <div class="span2">
                    <img src="/Static/gfx/logotype.png" />
                </div>
                <div class="span10">
                    @{Html.RenderPartial("Navigation");}
                </div>
            </div>
        </div>
        <hr />
        @RenderBody()
    </div>
</body>
</html>

Related topics

Do you find this information helpful? Please log in to provide feedback.

Last updated: Jun 16, 2021

Recommended reading