From ee7d62e58309031db6db4fc0f82ae6c2994db0ea Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Wed, 24 Jun 2020 18:22:10 +1000 Subject: [PATCH] Fixes #7148 - ensures we only check for SurfaceController routes (#8322) * See https://github.com/umbraco/Umbraco-CMS/issues/7148 for bug report and reason for fork and PR. * Fixes #7148 - ensures we only check for SurfaceController routes When finding the SurfaceController to post back to when using BeginUmbracoForm we weren't specifically checking for only SurfaceControllers routes since we just assumed it would be a SurfaceController route. This is problematic if using a SurfaceController simultaneously as an IRenderController with a custom front-end route since it will fail to find that controller to post back to. This is fixed by further filtering the controllers looked up to only include SurfaceControllers. Co-authored-by: Colin Wiseman --- src/Umbraco.Web/Mvc/RenderRouteHandler.cs | 45 +++++++++-------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs index c30f83170b..64bdac669f 100644 --- a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs @@ -178,37 +178,28 @@ namespace Umbraco.Web.Mvc using (RouteTable.Routes.GetReadLock()) { Route surfaceRoute; - if (postedInfo.Area.IsNullOrWhiteSpace()) + + //find the controller in the route table + var surfaceRoutes = RouteTable.Routes.OfType() + .Where(x => x.Defaults != null && + x.Defaults.ContainsKey("controller") && + x.Defaults["controller"].ToString().InvariantEquals(postedInfo.ControllerName) && + // Only return surface controllers + x.DataTokens["umbraco"].ToString().InvariantEquals("surface") && + // Check for area token if the area is supplied + (postedInfo.Area.IsNullOrWhiteSpace() ? !x.DataTokens.ContainsKey("area") : x.DataTokens["area"].ToString().InvariantEquals(postedInfo.Area))) + .ToList(); + + // If more than one route is found, find one with a matching action + if (surfaceRoutes.Count > 1) { - //find the controller in the route table without an area - var surfaceRoutes = RouteTable.Routes.OfType() - .Where(x => x.Defaults != null && - x.Defaults.ContainsKey("controller") && - x.Defaults["controller"].ToString().InvariantEquals(postedInfo.ControllerName) && - x.DataTokens.ContainsKey("area") == false).ToList(); - - // If more than one route is found, find one with a matching action - if (surfaceRoutes.Count > 1) - { - surfaceRoute = surfaceRoutes.FirstOrDefault(x => - x.Defaults["action"] != null && - x.Defaults["action"].ToString().InvariantEquals(postedInfo.ActionName)); - } - else - { - surfaceRoute = surfaceRoutes.SingleOrDefault(); - } - + surfaceRoute = surfaceRoutes.FirstOrDefault(x => + x.Defaults["action"] != null && + x.Defaults["action"].ToString().InvariantEquals(postedInfo.ActionName)); } else { - //find the controller in the route table with the specified area - surfaceRoute = RouteTable.Routes.OfType() - .SingleOrDefault(x => x.Defaults != null && - x.Defaults.ContainsKey("controller") && - x.Defaults["controller"].ToString().InvariantEquals(postedInfo.ControllerName) && - x.DataTokens.ContainsKey("area") && - x.DataTokens["area"].ToString().InvariantEquals(postedInfo.Area)); + surfaceRoute = surfaceRoutes.FirstOrDefault(); } if (surfaceRoute == null)