我有这条路线配置:
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 }
);
我的Sample控制器包含以下Action方法:
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");
}
如果我登陆localhost / RouteA页面并进行POST(通过按钮),它会将我重定向到localhost / RouteB / Confirmation。
如何让页面重定向到RouteA / Confirmation页面?
感谢。
答案 0 :(得分:1)
这里有2个问题。正如其他人指出的那样,您的HTTP POST需要更正。由于您要为2个不同的操作共享单个视图,因此最简单的方法是将actionName
参数设置为null
。这告诉MVC使用当前请求中的动作名称。
@{ 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>
}
第二个问题是RedirectToAction
生成网址时routeA
和routeB
之间的RedirectToRoute
调用不明确。由于第一次匹配总是获胜,因此您重定向到的URL始终是配置中的最高位置。
您可以使用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" });
}
}
明确指定路由名称(除现有匹配条件之外)来解决此问题。
@escaping
答案 1 :(得分:0)
你的问题很简单。 看看你的控制器,方法IndexA和IndexB,返回相同的视图; (来自你的评论)
@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; }
<h2>Index</h2>
using (Html.BeginForm("IndexB", "Sample", new { @id = "OrderForm" })) {
@Html.AntiForgeryToken()
<button type="submit" id="orderFormBtn">Extend my discount.</button>
}
当您点击提交时,您总是发帖到IndexB
有很多方法可以纠正这样一个简单的错误,例如,您可以使用2个不同的视图IndexA
和IndexB
并更改
using (Html.BeginForm("IndexB", "Sample", new { @id = "OrderForm" })) {
到
using (Html.BeginForm("IndexA", "Sample", new { @id = "OrderForm" })) {
答案 2 :(得分:0)
问题在于,routeA
和routeB
路由都可用于为IndexA
中的SampleController
操作创建链接。结果,BeginForm
将只是短路并选择将起作用的第一条路线,这可能是也可能不是正确的&#34;一个你正在寻找的人。要区分路线,请通过路线名称生成它们:
@using (Html.BeginRouteForm("routeA", new { @id = "OrderForm" })) {
然而,这只会让你得到&#34;默认&#34; routeA
路由,即/routeA/
。除路由的默认操作外,无法指定其他操作。
为了获得更大的灵活性,您可以使用属性路由,这将允许您为每个操作提供自定义路由名称,然后您可以使用该名称来获取该操作的URL。
除此之外,您需要以某种方式区分这两条路线,以便在生成URL时不应使用这些路线。对于标准路由来说,这通常很难做到,这就是为什么属性路由是一个更好的方法,如果你不再仅仅使用默认路由来解决所有问题。
或者,您可以重新构建项目以保持相同的URL结构,但可以更轻松地区分路径。通过使用区域,您可以指定应从中创建路径的区域。例如,假设您有RouteA
和RouteB
区域,则可以执行以下操作:
@using (Html.BeginForm("IndexB", "Sample", new { area = "RouteA", @id = "OrderForm" })) {
这意味着在每个区域都有SampleController
,但您可以使用继承来重用代码。