Description
Which Umbraco version are you using? (Please write the exact version, example: 10.1.0)
11.5.0
Bug summary
When using an UmbracoPageController to submit a form to a surface controller, the surface controller action method is called but "CurrentUmbracoPage" and "RedirectToCurrentUmbracoPage" do not work as expected.
Specifics
No response
Steps to reproduce
This issue is related to #13103. I've reused the testing code and made minor modifications to showcase the issue.
Steps to reproduce:
- Create a home page documenttype (alias homePage)
- Create a home page node
- Add the following code/templates:
Demo.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Logging;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Routing;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Web.Common;
using Umbraco.Cms.Web.Common.ApplicationBuilder;
using Umbraco.Cms.Web.Common.Controllers;
using Umbraco.Cms.Web.Website.Controllers;
namespace ToDelete5
{
public class DemoComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.Services.Configure<UmbracoPipelineOptions>(options =>
{
options.AddFilter(new UmbracoPipelineFilter(nameof(DemoPageController))
{
Endpoints = app => app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"DemoPageController",
"demo/{action}",
new { Controller = "DemoPage", Action = "Index" });
endpoints.MapControllerRoute(
"TestController",
"test/{action}",
new { Controller = "Test", Action = "Index" })
.ForUmbracoPage((actionExecutingContext) =>
{
var umbracoHelper = actionExecutingContext.HttpContext.RequestServices.GetService<UmbracoHelper>();
return umbracoHelper?.ContentAtRoot().First()!;
});
})
});
});
}
}
public class TestController : UmbracoPageController
{
public TestController(
ILogger<UmbracoPageController> logger,
ICompositeViewEngine compositeViewEngine)
: base(logger, compositeViewEngine)
{ }
[HttpGet]
public IActionResult Index() =>
View("~/Views/HomePage.cshtml", CurrentPage);
[HttpGet]
public IActionResult Subpage() =>
View("~/Views/HomePage.cshtml", CurrentPage);
}
public class DemoPageController : UmbracoPageController, IVirtualPageController
{
private readonly UmbracoHelper _umbracoHelper;
public DemoPageController(
ILogger<UmbracoPageController> logger,
ICompositeViewEngine compositeViewEngine,
UmbracoHelper umbracoHelper) : base(logger, compositeViewEngine) =>
_umbracoHelper = umbracoHelper;
public IPublishedContent? FindContent(ActionExecutingContext actionExecutingContext) =>
_umbracoHelper.ContentAtRoot().First();
[HttpGet]
public IActionResult Index() =>
View("~/Views/HomePage.cshtml", CurrentPage);
[HttpGet]
public IActionResult Subpage() =>
View("~/Views/HomePage.cshtml", CurrentPage);
}
public class DemoSurfaceController : SurfaceController
{
public DemoSurfaceController(
IUmbracoContextAccessor umbracoContextAccessor,
IUmbracoDatabaseFactory databaseFactory,
ServiceContext services,
AppCaches appCaches,
IProfilingLogger profilingLogger,
IPublishedUrlProvider publishedUrlProvider)
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
{ }
[HttpPost]
public IActionResult HandleCurrentPage(string name)
{
var currentPage = CurrentPage;
ViewData["name"] = name;
TempData["name"] = name;
return CurrentUmbracoPage();
}
[HttpPost]
public IActionResult HandleRedirectToCurrentPage(string name)
{
var currentPage = CurrentPage;
ViewData["name"] = name;
TempData["name"] = name;
return RedirectToCurrentUmbracoPage();
}
[HttpPost]
public IActionResult HandleRedirectToCurrentUrl(string name)
{
var currentPage = CurrentPage;
ViewData["name"] = name;
TempData["name"] = name;
return RedirectToCurrentUmbracoUrl();
}
}
}
HomePage.cshtml
@using Umbraco.Cms.Web.Common.PublishedModels;
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ContentModels.HomePage>
@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
@{
Layout = null;
}
<h1>@ViewContext.RouteData.Values["action"]: @Model.Name</h1>
@using (Html.BeginUmbracoForm<DemoSurfaceController>("HandleCurrentPage"))
{
@Html.TextBox("name")
<button type="submit">Handle Current Page</button>
}
@using (Html.BeginUmbracoForm<DemoSurfaceController>("HandleRedirectToCurrentPage"))
{
@Html.TextBox("name")
<button type="submit">Handle Redirect To Current Page</button>
}
@using (Html.BeginUmbracoForm<DemoSurfaceController>("HandleRedirectToCurrentUrl"))
{
@Html.TextBox("name")
<button type="submit">Handle Redirect To Current URL</button>
}
<p>View Data: @ViewData["name"]</p>
<p>Temp Data: @TempData["name"]</p>
Call either "/demo/subpage" (= UmbracoPageController, IVirtualPageController) or "/test/subpage" (= UmbracoPageController). The "Subpage" action is called as expected. Now click on:
- Handle Current Page (CurrentUmbracoPage): Returns the "Index" action instead of "Subpage".
- Handle Redirect To Current Page (RedirectToCurrentUmbracoPage): Returns 404 instead of "Subpage".
- Handle Redirect To Current URL (HandleRedirectToCurrentUrl): No issue here, works as expected.
The difference between the original testing code and the modified version is the inclusion of the "{action}" for the routing pattern. Testing it with any action other than "Index" showcases N°1. N°2 is broken with or without the additional "{action}" pattern.
Expected result / actual result
Expected: "CurrentUmbracoPage" and "RedirectToCurrentUmbracoPage" returns/calls the original action where the form submit came from.
Actual: "CurrentUmbracoPage" and "RedirectToCurrentUmbracoPage" returns the "Index" action and "404" respectively.
This item has been added to our backlog AB#34096