ASP.NET MVC - How to maintain ModelState from a different controller?

后端 未结 5 1560
时光取名叫无心 2021-02-20 18:43

I have a HomeController with an Index action that shows the Index.aspx view. It has a username/password login section. When the user clicks the submit button, it POSTs to a Lo

  • 2021-02-20 19:18

    As others have said it's common to return the view if validation fails but as you are calling from your account controller you will want to specify the full path of your view

    return View("~/Views/Home/Index.aspx", model);


    It is also common to have a seperate login page and redirect to that page if the login fails. Both pages will submit to the same login action. Facebook does this for example.


    As you only want to display an error message

    return RedirectToAction("Index", "Home", new { LoginAttempts = 1 });

    then in your Index action read the LoginAttempts parameter and choose to display the error message accordingly.

    0 讨论(0)
  • 2021-02-20 19:18

    Use TempData to save state between requests. Use special attributes for convenience as shown here.

    Few moments to mention:

    • Don't return View directly from your POST-action, respect Post-Redirect-Get pattern.
    • Don't overuse TempData. It's only supposed to save model state right before redirect and to retrieve it right after being redirected.
    0 讨论(0)
  • 2021-02-20 19:18

    Try using

    return View("Index", "Home", Model)
    0 讨论(0)
  • 2021-02-20 19:19

    Well you could always do this

    return View("~/Views/Home/Index.aspx", myModel);

    It's not a real redirect, the clients url will still point to /login/ but at least you have your modalstate

    0 讨论(0)
  • 2021-02-20 19:25

    Three options

    1. You could call the action directly, but the client side will not have its URL changed. So instead of calling RedirectToAction you could call the Index() method of the HomeController class directly.

      HomeController c = new HomeController();
      c.ViewData = this.ViewData;
      return c.Index(data);

      The one is a bit tricky. Maybe you will have to set other things as well apart from ViewData which is needed for ModelState.

    2. You could as well use TempData dictionary and fill it with whatever data you want and use that.

    3. The simplest one where you provide full path to the view

      return View("~/Views/Home/Index.aspx", data);

    A better suggestion used by big players

    If we look at how other sites do this kind of scenario. Take for instance Twitter (As @David says Facebook apparently does it the same). You can sign in from the Home/Index action (so to speak if it was developed using MVC). But when login fails it displays a separate login page, that displays validation errors. In your case it would be Account/SignIn. Which would make sense and you could directly return its view with validation errors. When everything would be ok, you'd do it as you do it now. Redirect back to Home/Index.

    0 讨论(0)