U4-7708 Using a RTE Macro Partial Form (SurfaceController) & Doctype Hijack Controller causes problem with submissions
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
using System.IO;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a special filter which is required for the RTE to be able to render Partial View Macros that
|
||||
/// contain forms when the RTE value is resolved outside of an MVC view being rendered
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The entire way that we support partial view macros that contain forms isn't really great, these forms
|
||||
/// need to be executed as ChildActions so that the ModelState,ViewData,TempData get merged into that action
|
||||
/// so the form can show errors, viewdata, etc...
|
||||
/// Under normal circumstances, macros will be rendered after a ViewContext is created but in some cases
|
||||
/// developers will resolve the RTE value in the controller, in this case the Form won't be rendered correctly
|
||||
/// with merged ModelState from the controller because the special DataToken hasn't been set yet (which is
|
||||
/// normally done in the UmbracoViewPageOfModel when a real ViewContext is available.
|
||||
/// So we need to detect if the currently rendering controller is IRenderController and if so we'll ensure that
|
||||
/// this DataToken exists before the action executes in case the developer resolves an RTE value that contains
|
||||
/// a partial view macro form.
|
||||
/// </remarks>
|
||||
internal class EnsurePartialViewMacroViewContextFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(ActionExecutingContext filterContext)
|
||||
{
|
||||
//ignore anything that is not IRenderController
|
||||
if ((filterContext.Controller is IRenderController) == false)
|
||||
return;
|
||||
|
||||
var viewCtx = new ViewContext(
|
||||
filterContext.Controller.ControllerContext,
|
||||
new DummyView(),
|
||||
filterContext.Controller.ViewData, filterContext.Controller.TempData,
|
||||
new StringWriter());
|
||||
|
||||
//set the special data token
|
||||
filterContext.RequestContext.RouteData.DataTokens[Constants.DataTokenCurrentViewContext] = viewCtx;
|
||||
}
|
||||
|
||||
private class DummyView : IView
|
||||
{
|
||||
public void Render(ViewContext viewContext, TextWriter writer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,10 +120,9 @@ namespace Umbraco.Web.Mvc
|
||||
base.InitializePage();
|
||||
if (ViewContext.IsChildAction == false)
|
||||
{
|
||||
if (ViewContext.RouteData.DataTokens.ContainsKey(Constants.DataTokenCurrentViewContext) == false)
|
||||
{
|
||||
ViewContext.RouteData.DataTokens.Add(Constants.DataTokenCurrentViewContext, ViewContext);
|
||||
}
|
||||
//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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -343,6 +343,7 @@
|
||||
<Compile Include="Models\Mapping\PropertyGroupDisplayResolver.cs" />
|
||||
<Compile Include="Models\PublishedContentWithKeyBase.cs" />
|
||||
<Compile Include="Mvc\ControllerContextExtensions.cs" />
|
||||
<Compile Include="Mvc\EnsurePartialViewMacroViewContextFilterAttribute.cs" />
|
||||
<Compile Include="Mvc\IRenderController.cs" />
|
||||
<Compile Include="Mvc\ModelBindingException.cs" />
|
||||
<Compile Include="Mvc\RenderIndexActionSelectorAttribute.cs" />
|
||||
|
||||
@@ -198,6 +198,9 @@ namespace Umbraco.Web
|
||||
//Wrap viewengines in the profiling engine
|
||||
WrapViewEngines(ViewEngines.Engines);
|
||||
|
||||
//add global filters
|
||||
ConfigureGlobalFilters();
|
||||
|
||||
//set routes
|
||||
CreateRoutes();
|
||||
|
||||
@@ -224,6 +227,11 @@ namespace Umbraco.Web
|
||||
return this;
|
||||
}
|
||||
|
||||
internal static void ConfigureGlobalFilters()
|
||||
{
|
||||
GlobalFilters.Filters.Add(new EnsurePartialViewMacroViewContextFilterAttribute());
|
||||
}
|
||||
|
||||
internal static void WrapViewEngines(IList<IViewEngine> viewEngines)
|
||||
{
|
||||
if (viewEngines == null || viewEngines.Count == 0) return;
|
||||
|
||||
Reference in New Issue
Block a user