Welcome to the navigation

Dolor in ipsum ut et minim excepteur qui cupidatat laborum, dolor pariatur, id culpa aliquip nisi ea ullamco nulla esse adipisicing amet, fugiat proident, in. Sed adipisicing cupidatat id in nisi excepteur minim irure dolore ut officia eiusmod exercitation pariatur, qui aute in laboris consequat, occaecat velit ex duis proident

Yeah, this will be replaced... But please enjoy the search!

Accessing current IContent instance in Episerver MVC View

I needed to access the current content model (IContent) in Episerver MVC views (included partial loaded) using the always available ViewContext. 

TLDR;

var content = ViewContext.IsChildAction
    ? (IContent)ViewContext.RouteData.Values["currentContent"]
    : (IContent)ViewContext.RouteData.DataTokens.FirstOrDefault(x => x.Key.Equals("routedData")).Value;

 

What is a WebViewPage?

Any razor view (cshtml) file will inherit from System.Web.Mvc.WebViewPage, which also is why we have lots of utilities like HTML helpers, the actual model ViewBag, ViewData and ViewContext. 

RouteData

Since ViewContext is resolved in the views we are able to access the ControllerContext (ViewContext inherits from ControllerContext), which is where we can access the RouteData property in order to resolve which content model that created the instance of the current view, partial or not.

 

Block or Page?

To resolve a Block instance

(IContent)ViewContext.RouteData.Values["currentContent"]

 

To resolve a Page instance

(IContent)ViewContext.RouteData.DataTokens.FirstOrDefault(x => x.Key.Equals("routedData")).Value

Page instances can also be resolved by using the GetRoutedData extension method

@using EPiServer.Web.Routing;
ViewContext.RequestContext.GetRoutedData<IContent>()

 

What to use? 

In order to figure out if we shall resolve a block or a page, we can use the IsChildAction property from the ControllerContext.

var content = ViewContext.IsChildAction
    ? (IContent)ViewContext.RouteData.Values["currentContent"]
    : (IContent)ViewContext.RouteData.DataTokens.FirstOrDefault(x => x.Key.Equals("routedData")).Value;

 

The Values is a property in the RouteData class implementing a RouteValueDictionary that we are able to cast into IContent. This is made possible since .NET Framework is able to use the RequestContext after casting the DataTokens to a ControllerContext. 

 

Further use

There are surely lots of use cases for this kind of implementations. I.e. to resolve the ContentType

@using EPiServer.ServiceLocation
@using EPiServer.DataAbstraction
var contentTypeRepository = ServiceLocator.Current.GetInstance();
var contentType = contentTypeRepository.Load(content.ContentTypeID);