ViewContext.ParentActionViewContext is null when trying to access parent ContentArea in EPiServer

972 views Asked by At

I'm trying to use the approach shown here to allow my blocks in EPiServer to query their index within a parent ContentArea. I already do this in another project (project A) and am now trying to do it again in a new project (project B). But for some reason in the new project, the ViewContext.ParentActionViewContext is null. I started comparing the differences between the two and I notice in Project A, IsChildAction is true and the RouteData.DataTokens contains only one key = 'ParentActionDataContext', but in Project B, IsChildAction is false and The RouteData.DataTokens contains all the keys for the main request. Ok, so given that the description of the ParentActionViewContext property is:

An object that contains the view context information for the parent action method.

It makes sense that it would be null in Project B if there is no child action. The problem is, I don't know why Project A executes rendering the ContentArea as a child action but Project B does not. Comparing the call stacks, I can see that it branches off in the two different directions within the EPiServer assembly (top 2 frames of each stack below):

Project A

EPiServer.dll!EPiServer.Web.Mvc.PartialRequest.RenderAction(System.Web.Mvc.HtmlHelper helper, string action, string controller, object routeValues) Unknown
EPiServer.dll!EPiServer.Web.Mvc.MvcContentRenderer.Render(System.Web.Mvc.HtmlHelper helper, EPiServer.Web.Mvc.PartialRequest partialRequestHandler, EPiServer.Core.IContentData contentData, EPiServer.DataAbstraction.TemplateModel templateModel) Unknown
EPiServer.dll!EPiServer.Web.Mvc.Html.IContentDataExtensions.RenderContentData(System.Web.Mvc.HtmlHelper html, EPiServer.Core.IContentData contentData, bool isContentInContentArea, EPiServer.DataAbstraction.TemplateModel templateModel, EPiServer.Web.Mvc.IContentRenderer contentRenderer)  Unknown
EPiServer.dll!EPiServer.Web.Mvc.Html.ContentAreaRenderer.RenderContentAreaItem(System.Web.Mvc.HtmlHelper htmlHelper, EPiServer.Core.ContentAreaItem contentAreaItem, string templateTag, string htmlTag, string cssClass)   Unknown
EPiServer.dll!EPiServer.Web.Mvc.Html.ContentAreaRenderer.RenderContentAreaItems(System.Web.Mvc.HtmlHelper htmlHelper, System.Collections.Generic.IEnumerable<EPiServer.Core.ContentAreaItem> contentAreaItems)  Unknown
EPiServer.dll!EPiServer.Web.Mvc.Html.ContentAreaRenderer.Render(System.Web.Mvc.HtmlHelper htmlHelper, EPiServer.Core.ContentArea contentArea)   Unknown
EPiServer.dll!EPiServer.Web.Mvc.Html.ContentAreaExtensions.RenderContentArea(System.Web.Mvc.HtmlHelper htmlHelper, EPiServer.Core.ContentArea contentArea)  Unknown
App_Web_zaun2obg.dll!ASP.util_views_shared_displaytemplates_contentarea_ascx.__Render__control1(System.Web.UI.HtmlTextWriter __w, System.Web.UI.Control parameterContainer) Line 4  C#

Project B

EPiServer.dll!EPiServer.Web.Mvc.MvcContentRenderer.HandleRenderTemplateWithViewEngine(System.Web.Mvc.HtmlHelper helper, EPiServer.Core.IContentData contentData, EPiServer.DataAbstraction.TemplateModel templateModel) Unknown
EPiServer.dll!EPiServer.Web.Mvc.MvcContentRenderer.Render(System.Web.Mvc.HtmlHelper helper, EPiServer.Web.Mvc.PartialRequest partialRequestHandler, EPiServer.Core.IContentData contentData, EPiServer.DataAbstraction.TemplateModel templateModel) Unknown
EPiServer.dll!EPiServer.Web.Mvc.Html.IContentDataExtensions.RenderContentData(System.Web.Mvc.HtmlHelper html, EPiServer.Core.IContentData contentData, bool isContentInContentArea, EPiServer.DataAbstraction.TemplateModel templateModel, EPiServer.Web.Mvc.IContentRenderer contentRenderer)  Unknown
EPiServer.dll!EPiServer.Web.Mvc.Html.ContentAreaRenderer.RenderContentAreaItem(System.Web.Mvc.HtmlHelper htmlHelper, EPiServer.Core.ContentAreaItem contentAreaItem, string templateTag, string htmlTag, string cssClass)   Unknown
EPiServer.dll!EPiServer.Web.Mvc.Html.ContentAreaRenderer.RenderContentAreaItems(System.Web.Mvc.HtmlHelper htmlHelper, System.Collections.Generic.IEnumerable<EPiServer.Core.ContentAreaItem> contentAreaItems)  Unknown
EPiServer.dll!EPiServer.Web.Mvc.Html.ContentAreaRenderer.Render(System.Web.Mvc.HtmlHelper htmlHelper, EPiServer.Core.ContentArea contentArea)   Unknown
EPiServer.dll!EPiServer.Web.Mvc.Html.ContentAreaExtensions.RenderContentArea(System.Web.Mvc.HtmlHelper htmlHelper, EPiServer.Core.ContentArea contentArea)  Unknown
App_Web_myevwxkt.dll!ASP.util_views_shared_displaytemplates_contentarea_ascx.__Render__control1(System.Web.UI.HtmlTextWriter __w, System.Web.UI.Control parameterContainer) Line 4  C#

But I call both the same way:

Project A:

@Html.PropertyFor(m => m.CurrentPage.WallBlocks)

Project B:

@Html.PropertyFor(m => m.CurrentPage.DepartmentalSupportBlocks)

Any idea what's going on or how I can make it work so I can get at the parent ContentArea in my Html helper?

1

There are 1 answers

1
xr280xr On BEST ANSWER

I found the problem. I was correct in thinking that the ParentActionViewContext was null because the block was not being executed as a child view. The reason seems to be because my block did not have a controller. It looks like EPiServer will render Blocks that have a controller as child Actions, but those that do not have a controller as part of the same request. I guess this is the reason why it's recommended to not use a controller for your Blocks for efficiency reasons. However, if you need information about the parent ContentArea, it seems you do need to have a controller.

P.S. Make sure you return PartialView(...) not View(...) from your block controller so you don't spend an extra couple hours trying to figure out why it's yelling at you saying,

The model item passed into the dictionary is of type 'Castle.Proxies.[MyBlock]Proxy', but this dictionary requires a model item of type '[My default layout's model type]'