ReturnUrl 指向一个 ActionResult
ReturnUrl Points to an ActionResult
场景是这样的:
- 从头开始一个 MVC 项目
- 用 [Authorize] 属性修饰的测试控制器
- 用户登录并定向到主页
- 用户单击重定向到
TestController
的 Index
方法的 link
- 用户等待表单身份验证超时 60 秒
- 用户单击 link 调用驻留在
TestController
上的 ActionMethod
- MVC 框架将用户重定向到登录页面并将 ActionMethod 名称附加到 URL 而不是附加
Index
操作方法
测试控制器:
[Authorize]
public class TestController : Controller
{
// GET: Test
public ViewResult Index()
{
return View();
}
[ValidateInput(false)]
public ActionResult ActionTest()
{
return new EmptyResult();
}
}
家庭控制器:
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
账户控制器:
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
try
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
return RedirectToAction(controllerName: "Home", actionName: "Index");
}
catch
{
return View(model);
}
}
return View(model);
}
}
Login.chtml
@model TestLoginProject.Models.LoginViewModel
@{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
.....................
</head>
<body>
<div class="container">
@using (@Html.BeginForm("Login", "Account", new { returnUrl = Request.QueryString["ReturnUrl"] }, FormMethod.Post, new { @class = "form-signin" }))
{
@Html.AntiForgeryToken()
....................
....................
}
</div>
</body>
</html>
网络配置
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="1" />
</authentication>
returnurl的期望是:
http://localhost:2441/Account/Login?ReturnUrl=%2fTest%2fIndex
相反,当前值为:
http://localhost:2441/Account/Login?ReturnUrl=%2fTest%2fActionTest
备注:
- 当用户在超时后单击 link 时,在重定向到登录页面之前不会命中任何测试操作
- 在 VS2017 中从头开始一个 Empty MVC 项目时,所有路由都是默认提供的
这是您提到的正常行为!
The MVC framework redirects user to Login page and attaches the
ActionMethod name to the URL instead of attaching the Index
Action Method
非常感谢 MVC 安全管道。当您使用 表单身份验证 而用户未经过身份验证或授权时, ASP.NET 安全管道重定向到登录页面并将 returnUrl
作为参数传递 等于重定向到登录页面的页面(这里是需要授权的控制器操作,您通过单击 link 调用)。
所以在这里你不能期望 index(当前加载的页面没有有效和持久的身份验证),随后 ActionMethod
调用安全管道和 returnurl
被及时枚举。
注意这是因为Controller和View之间的同步通信。
场景是这样的:
- 从头开始一个 MVC 项目
- 用 [Authorize] 属性修饰的测试控制器
- 用户登录并定向到主页
- 用户单击重定向到
TestController
的Index
方法的 link - 用户等待表单身份验证超时 60 秒
- 用户单击 link 调用驻留在
TestController
上的 ActionMethod
- MVC 框架将用户重定向到登录页面并将 ActionMethod 名称附加到 URL 而不是附加
Index
操作方法
测试控制器:
[Authorize]
public class TestController : Controller
{
// GET: Test
public ViewResult Index()
{
return View();
}
[ValidateInput(false)]
public ActionResult ActionTest()
{
return new EmptyResult();
}
}
家庭控制器:
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
账户控制器:
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
try
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
return RedirectToAction(controllerName: "Home", actionName: "Index");
}
catch
{
return View(model);
}
}
return View(model);
}
}
Login.chtml
@model TestLoginProject.Models.LoginViewModel
@{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
.....................
</head>
<body>
<div class="container">
@using (@Html.BeginForm("Login", "Account", new { returnUrl = Request.QueryString["ReturnUrl"] }, FormMethod.Post, new { @class = "form-signin" }))
{
@Html.AntiForgeryToken()
....................
....................
}
</div>
</body>
</html>
网络配置
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="1" />
</authentication>
returnurl的期望是:
http://localhost:2441/Account/Login?ReturnUrl=%2fTest%2fIndex
相反,当前值为:
http://localhost:2441/Account/Login?ReturnUrl=%2fTest%2fActionTest
备注:
- 当用户在超时后单击 link 时,在重定向到登录页面之前不会命中任何测试操作
- 在 VS2017 中从头开始一个 Empty MVC 项目时,所有路由都是默认提供的
这是您提到的正常行为!
The MVC framework redirects user to Login page and attaches the ActionMethod name to the URL instead of attaching the
Index
Action Method
非常感谢 MVC 安全管道。当您使用 表单身份验证 而用户未经过身份验证或授权时, ASP.NET 安全管道重定向到登录页面并将 returnUrl
作为参数传递 等于重定向到登录页面的页面(这里是需要授权的控制器操作,您通过单击 link 调用)。
所以在这里你不能期望 index(当前加载的页面没有有效和持久的身份验证),随后 ActionMethod
调用安全管道和 returnurl
被及时枚举。
注意这是因为Controller和View之间的同步通信。