diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs b/src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs index 3bc7f57385..946bef7d71 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs @@ -456,6 +456,36 @@ namespace Microsoft.AspNetCore.Mvc return new LocalRedirectResult(localUrl: localUrl, permanent: true, preserveMethod: true); } + /// + /// Redirects () to an action with the same name as current one. + /// The 'controller' and 'action' names are retrieved from the ambient values of the current request. + /// + /// The created for the response. + /// + /// A POST request to an action named "Product" updates a product and redirects to an action, also named + /// "Product", showing details of the updated product. + /// + /// [HttpGet] + /// public IActionResult Product(int id) + /// { + /// var product = RetrieveProduct(id); + /// return View(product); + /// } + /// + /// [HttpPost] + /// public IActionResult Product(int id, Product product) + /// { + /// UpdateProduct(product); + /// return RedirectToAction(); + /// } + /// + /// + [NonAction] + public virtual RedirectToActionResult RedirectToAction() + { + return RedirectToAction(actionName: null); + } + /// /// Redirects () to the specified action using the . /// diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/BasicTests.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/BasicTests.cs index ed0a8c0164..0a6009a79f 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/BasicTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/BasicTests.cs @@ -402,6 +402,24 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests Assert.Equal(expected, response.Trim()); } + [Fact] + public async Task RedirectToAction_WithEmptyActionName_UsesAmbientValue() + { + // Arrange + var product = new List>(); + product.Add(new KeyValuePair("SampleInt", "20")); + + // Act + var response = await Client.PostAsync("/Home/Product", new FormUrlEncodedContent(product)); + + // Assert + Assert.Equal(HttpStatusCode.Redirect, response.StatusCode); + Assert.NotNull(response.Headers.Location); + Assert.Equal("/Home/Product", response.Headers.Location.ToString()); + + var responseBody = await Client.GetStringAsync("/Home/Product"); + Assert.Equal("Get Product", responseBody); + } [Fact] public async Task ActionMethod_ReturningActionMethodOfT_WithBadRequest() { diff --git a/test/WebSites/BasicWebSite/Controllers/HomeController.cs b/test/WebSites/BasicWebSite/Controllers/HomeController.cs index c6554d7c76..0730aa55b6 100644 --- a/test/WebSites/BasicWebSite/Controllers/HomeController.cs +++ b/test/WebSites/BasicWebSite/Controllers/HomeController.cs @@ -108,5 +108,17 @@ namespace BasicWebSite.Controllers { return ControllerContext.ActionDescriptor.Properties["description"].ToString(); } + + [HttpGet] + public IActionResult Product() + { + return Content("Get Product"); + } + + [HttpPost] + public IActionResult Product(Product product) + { + return RedirectToAction(); + } } } \ No newline at end of file