Turn Your EPiServer 7 MVC Page/Block Model into a View Model using the Ignore Attribute

March 2022 Update: This post was originally written for EPiServer version 7. In 2021, Episerver (now known as Optimizely) released version 12. While the approach provided in this post is still relevant to the current version, I recommend to create view models instead of using the [Ignore] attribute. Seriously... Don't do this.

If you've ever built a large MVC application, you'll know that your project can sometimes contain a large amount of files, some of which act as a layer of code between two aspects of the application. One such file is the view model, which is used to transfer data from the controller to the view.

When developing with EPiServer 7 MVC, in most situations you can use the page or block model directly in your view. There are some cases, however, where you'll find yourself using a separate view model to satisfy the needs of the view.

An Example

For example, say you have a page model with a LinkItemCollection property, but the view needs a List of a particular page type. You could easily create two files for this, the page model and the view model:

Page Model

[ContentType(GUID = "00000000-0000-0000-0000-000000000000")]
public class ListPage : PageData
{
    public virtual LinkItemCollection PageCollection { get; set; }
}

View Model

public class ListPageViewModel
{
    public List<SimplePage> PageList{ get; set; }
}

However, you can simplify this into one file by using the [Ignore] attribute on the property. The [Ignore] attribute prevents EPiServer from registering the property as an editable page/block type property.

[ContentType(GUID = "00000000-0000-0000-0000-000000000000")]
public class ListPage : PageData
{
    public virtual LinkItemCollection PageCollection { get; set; }

    [Ignore]
    public virtual List<SimplePage> PageList{ get; set; }
}

Why Use This?

While I completely understand that some people may disagree with this idea (primarily because of the many benefits that the view model provides), I've found this useful particularly for a couple reasons:

Fewer lines of code by eliminating edit hints - By turning the page/block model into a view model, you don't need to add on-page editing hints in the ViewData in your controller:

var editHints = this.ViewData.GetEditHints<ListPageViewModel, ListPage>();
editHints.AddConnection(vm => vm.PageList, pm => pm.PageCollection);

Instead, you can use EPiServer's EditAttributes HTML helper, and use on the properties in the page/block model to provide the proper on-page editing:

@model ListPage

<div @Html.EditAttributes(m=> m.PageCollection)>
    @foreach (var page in Model.PageList)
    {
        ... some code ...
    }
</div>

Fewer files to maintain by eliminating a layer of code - By using the [Ignore] attribute, you can look at the page/block model and see exactly what the view needs, whether the property is for editing purposes or for displaying purposes. This also makes it easier to update or maintain the code in future changes.