ASP.NET MVC - 如何从不同的控制器维护ModelState?

Rap*_*Rap 10 validation asp.net-mvc redirect login

我有一个带有Index操作的HomeController,它显示了Index.aspx视图.它有一个用户名/密码登录部分.当用户单击提交按钮时,它会POST到AccountController中的Login操作.

        <% Html.BeginForm("Login", "Account", FormMethod.Post); %>
Run Code Online (Sandbox Code Playgroud)

在该操作中,它测试用户名/密码有效性,如果无效,则将用户发回"登录"页面,并显示凭据错误的消息.

    [HttpPost]
    public ActionResult Login(LoginViewModel Model, string ReturnUrl)
    {
        User user = MembershipService.ValidateUser(Model.UserName, Model.Password);
        if (user != null)
        {
            //Detail removed here
            FormsService.SignIn(user.ToString(), Model.RememberMe);
            return Redirect(ReturnUrl);
        }
        else
        {
            ModelState.AddModelError("", "The user name or password provided is incorrect.");
        }
        // If we got this far, something failed, redisplay form
        return RedirectToAction("Index", "Home");  // <-- Here is the problem.  ModelState is lost.
    }
Run Code Online (Sandbox Code Playgroud)

但问题出在这里:ValidationSummary始终是空白的,因为我们在RedirectToAction时丢失了Model.

所以问题是:如何在没有重定向的情况下将用户发送到不同控制器上的操作?

Dav*_*enn 7

正如其他人所说,如果验证失败,则返回视图是很常见的,但是当您从帐户控制器呼叫时,您需要指定视图的完整路径

return View("~/Views/Home/Index.aspx", model);
Run Code Online (Sandbox Code Playgroud)

要么

如果登录失败,通常会有一个单独的登录页面并重定向到该页面.两个页面都将提交相同的登录操作.Facebook就是这样做的.

要么

因为您只想显示错误消息

return RedirectToAction("Index", "Home", new { LoginAttempts = 1 });
Run Code Online (Sandbox Code Playgroud)

然后在您的Index操作中读取LoginAttempts参数并选择相应地显示错误消息.


Vas*_*y R 7

用于TempData在请求之间保存状态.如使用特殊属性为方便起见,这里.

几点提及:

  • 不要直接从POST操作返回View,请尊重Post-Redirect-Get模式.
  • 不要过度使用TempData.它不仅应该保存模型状态权利之前重定向和右侧被重定向后进行检索.