diff --git a/src/Umbraco.Web/Mvc/EnsurePartialViewMacroViewContextFilterAttribute.cs b/src/Umbraco.Web/Mvc/EnsurePartialViewMacroViewContextFilterAttribute.cs
index afd40330ea..625b67b2b2 100644
--- a/src/Umbraco.Web/Mvc/EnsurePartialViewMacroViewContextFilterAttribute.cs
+++ b/src/Umbraco.Web/Mvc/EnsurePartialViewMacroViewContextFilterAttribute.cs
@@ -21,20 +21,46 @@ namespace Umbraco.Web.Mvc
///
internal class EnsurePartialViewMacroViewContextFilterAttribute : ActionFilterAttribute
{
+ ///
+ /// Ensures the custom ViewContext datatoken is set before the RenderController action is invoked,
+ /// this ensures that any calls to GetPropertyValue with regards to RTE or Grid editors can still
+ /// render any PartialViewMacro with a form and maintain ModelState
+ ///
+ ///
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//ignore anything that is not IRenderController
- if ((filterContext.Controller is IRenderController) == false)
+ if ((filterContext.Controller is IRenderController) == false && filterContext.IsChildAction == false)
return;
+ SetViewContext(filterContext);
+ }
+
+ ///
+ /// Ensures that the custom ViewContext datatoken is set after the RenderController action is invoked,
+ /// this ensures that any custom ModelState that may have been added in the RenderController itself is
+ /// passed onwards in case it is required when rendering a PartialViewMacro with a form
+ ///
+ /// The filter context.
+ public override void OnResultExecuting(ResultExecutingContext filterContext)
+ {
+ //ignore anything that is not IRenderController
+ if ((filterContext.Controller is IRenderController) == false && filterContext.IsChildAction == false)
+ return;
+
+ SetViewContext(filterContext);
+ }
+
+ private void SetViewContext(ControllerContext controllerContext)
+ {
var viewCtx = new ViewContext(
- filterContext.Controller.ControllerContext,
- new DummyView(),
- filterContext.Controller.ViewData, filterContext.Controller.TempData,
+ controllerContext,
+ new DummyView(),
+ controllerContext.Controller.ViewData, controllerContext.Controller.TempData,
new StringWriter());
//set the special data token
- filterContext.RequestContext.RouteData.DataTokens[Constants.DataTokenCurrentViewContext] = viewCtx;
+ controllerContext.RequestContext.RouteData.DataTokens[Constants.DataTokenCurrentViewContext] = viewCtx;
}
private class DummyView : IView
diff --git a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs
index 0c45c24c4a..3d1a41d289 100644
--- a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs
+++ b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs
@@ -120,9 +120,13 @@ namespace Umbraco.Web.Mvc
base.InitializePage();
if (ViewContext.IsChildAction == false)
{
- //always ensure the special data token is set - this is used purely for partial view macros that contain forms
- // and mostly just when rendered within the RTE
- ViewContext.RouteData.DataTokens[Constants.DataTokenCurrentViewContext] = ViewContext;
+ //this is used purely for partial view macros that contain forms
+ // and mostly just when rendered within the RTE - This should already be set with the
+ // EnsurePartialViewMacroViewContextFilterAttribute
+ if (ViewContext.RouteData.DataTokens.ContainsKey(Constants.DataTokenCurrentViewContext) == false)
+ {
+ ViewContext.RouteData.DataTokens.Add(Constants.DataTokenCurrentViewContext, ViewContext);
+ }
}
}