I've got this route configuration:
routes.MapRoute(
"routeB",
"routeB/{action}/{id}",
new { controller = "Sample", action = "IndexB", id = UrlParameter.Optional });
routes.MapRoute(
"routeA",
"routeA/{action}/{id}",
new { controller = "Sample", action = "IndexA", id = UrlParameter.Optional });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
And my Sample controller contains these Action methods:
public ActionResult IndexA(string id)
{
return View("Index");
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult IndexA()
{
return RedirectToAction("Confirmation");
}
public ActionResult Confirmation()
{
return View("Confirmation");
}
public ActionResult IndexB(string id)
{
return View("Index");
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult IndexB()
{
return RedirectToAction("Confirmation");
}
If I land on the localhost/RouteA page and make a POST (via a button) it redirects me to localhost/RouteB/Confirmation.
How can I get the page to redirect to the RouteA/Confirmation page?
Thanks.
There are 2 issues here. As others have pointed out, your HTTP POST needs to be corrected. Since you are sharing a single view for 2 different actions, the simplest way to do that is to set the actionName
parameter to null
. This tells MVC to use the action name from the current request.
@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; }
<h2>Index</h2>
@using (Html.BeginForm(null, "Sample", new { id = "OrderForm" }))
{
@Html.AntiForgeryToken()
<button type="submit" id="orderFormBtn">Extend my discount.</button>
}
The second issue is that the RedirectToAction
call is ambiguous between routeA
and routeB
when generating the URL. Since the first match always wins, the URL you are redirecting to is always the top one in your configuration.
You can fix this problem by using RedirectToRoute
to specify the route name (in addition to your existing matching criteria) explicitly.
public class SampleController : Controller
{
public ActionResult IndexA(string id)
{
return View("Index");
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult IndexA()
{
return RedirectToRoute("routeA", new { action = "Confirmation" });
}
public ActionResult Confirmation()
{
return View("Confirmation");
}
public ActionResult IndexB(string id)
{
return View("Index");
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult IndexB()
{
// Note that changing this one to RedirectToRoute is not strictly
// necessary, but may be more clear to future analysis of the configuration.
return RedirectToRoute("routeB", new { action = "Confirmation" });
}
}