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 <sayhi@codeitwise.co.uk>
This commit is contained in:
Shannon Deminick
2020-06-24 18:22:10 +10:00
committed by GitHub
parent fee6ef0fb0
commit ee7d62e583

View File

@@ -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<Route>()
.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<Route>()
.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<Route>()
.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)