Pass controller error to the view

1

I am making a basic login form and find myself in the following situation:

I want to return an error if the user does not exist in the database and I am doing this using "ModelState.AddModelError".

However, when I log in I go back to the form, but the error does not appear ....

Controller:

public class LoginController : Controller
    {

        private readonly UsuarioService _usuarioService;

        public LoginController(UsuarioService usuarioService)
        {
            _usuarioService = usuarioService;
        }

        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Logar(Usuario usuario)
        {

            if (!ModelState.IsValid)
            {
                return RedirectToAction(nameof(Index));
            }

            Usuario user = await _usuarioService
                .BuscarUserAsync(x => x.Username == usuario.Username && x.Senha == usuario.Senha);


            //Este é o código que testa o que foi citado acima
            if (user == null)
            {
                ModelState.AddModelError("Aviso", "Usuario ou senha invalidos");
                return RedirectToAction(nameof(Index));
            }

            var claims = new List<Claim>
            {
               new Claim(ClaimTypes.Name, usuario.Username)
            };

            var userIdentity = new ClaimsIdentity(claims, "login");

            ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);

            await HttpContext.SignInAsync(principal);

            return Redirect("/");
        }
    }

View:

@model Site.Models.Usuario;
@{
    ViewData["Title"] = "Login";
}

<h2>@ViewData["Title"]</h2>


<h3>@Html.ValidationMessage("Aviso")</h3>

<div class="row">
    <div class="col-md-6">

        <form asp-action="Logar">
            <div class="form-group">
                <label asp-for="Username" class="control-label"></label>
                <input asp-for="Username" class="form-control" />
            </div>
            <div class="form-group">
                <label asp-for="Senha" class="control-label"></label>
                <input asp-for="Senha" type="password" class="form-control" />
            </div>
            <div class="form-group">
                <input type="submit" value="Logar" class="btn btn-default" />
            </div>
        </form>

    </div>
</div>
    
asked by anonymous 18.09.2018 / 16:53

1 answer

1

Since you used RedirectToAction(nameof(Index)); , the user will be redirected to Index and the ModelState is re-created, so you do not have the value you added.

There are a few ways to work around, one of which is using TempData, like this:

In Action Logar:

//Este é o código que testa o que foi citado acima
 if (user == null)
 {
     //ModelState.AddModelError("Aviso", "Usuario ou senha invalidos");
     TempData["LoginError"] = "Usuario ou senha invalidos";
     return RedirectToAction(nameof(Index));
 }

In the Action Index:

public IActionResult Index()
{
     // Se TempData contém a mensagem de erro, então adiciona no ModelState.
     if (TempData["LoginError"] != null)
     {
           ModelState.AddModelError(string.Empty, TempData["LoginError"].ToString());
     }
     return View();
}

In the View Index:

<div>
    @Html.ValidationSummary(true)
</div>
    
18.09.2018 / 18:53