From b9af6f631a38696010a03a3efb8e211fd2abc5fa Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 22 Mar 2016 11:23:09 +0100 Subject: [PATCH 1/2] U4-8220 ModelState and ViewData is not carried through when using the obsolete Content.GetGridHtml method --- ...tialViewMacroViewContextFilterAttribute.cs | 34 ++++++++++++++++--- .../Mvc/UmbracoViewPageOfTModel.cs | 10 ++++-- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web/Mvc/EnsurePartialViewMacroViewContextFilterAttribute.cs b/src/Umbraco.Web/Mvc/EnsurePartialViewMacroViewContextFilterAttribute.cs index afd40330ea..5be98f338b 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) 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) + 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); + } } } From 43e23829ae3affbccbb95e1ee4ca330949145336 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 23 Mar 2016 10:06:13 +0100 Subject: [PATCH 2/2] updates EnsurePartialViewMacroViewContextFilterAttribute to check for child actions --- .../Mvc/EnsurePartialViewMacroViewContextFilterAttribute.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/Mvc/EnsurePartialViewMacroViewContextFilterAttribute.cs b/src/Umbraco.Web/Mvc/EnsurePartialViewMacroViewContextFilterAttribute.cs index 5be98f338b..625b67b2b2 100644 --- a/src/Umbraco.Web/Mvc/EnsurePartialViewMacroViewContextFilterAttribute.cs +++ b/src/Umbraco.Web/Mvc/EnsurePartialViewMacroViewContextFilterAttribute.cs @@ -30,7 +30,7 @@ namespace Umbraco.Web.Mvc 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); @@ -45,7 +45,7 @@ namespace Umbraco.Web.Mvc public override void OnResultExecuting(ResultExecutingContext 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);