Ошибка проверки формы всегда видна в asp.netcore - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть простая форма входа в систему с одним полем ввода, например:

<form asp-action="SendLoginEmail" method="post">
    <div class="row">
        <input asp-for="EmailAddress" placeholder="Adresse mail" class="form-control"/>
        <div class="row">
            <span asp-validation-for="EmailAddress"></span>
            @if (Model != null && !string.IsNullOrWhiteSpace(Model.ErrorMessage))
            {
                <span class="field-validation-error">@Model.ErrorMessage</span>
            }
        </div>
    </div>
    <div class="row">
        <button type="submit" id="login-button" class="challenge-action-item green-action-button link-button">Continuer</button>
    </div>
</form>

Вот контроллеры:

[HttpGet("login")]
[AllowAnonymous]
public IActionResult LoginGet(LoginModel model)
{
    return View(model);
}

[HttpPost("login")]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> LoginPost(LoginModel model)
{
    if (!ModelState.IsValid)
    {
        return View("Login", model);
    }
    ...
}

[HttpPost("login")]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Whatever(LoginModel model)
{
    var error = "The one time login link has expired";
    return RedirectToAction("Login", new LoginModel() {ErrorMessage = error});
}

Помимо ошибок валидации, я также заполняю сообщение ErrorMessage из модели, чтобы сообщить пользователю о потенциальных ошибках на стороне сервера, таких как (адрес электронной почты не распознан, истек срок действия ссылки для входа в систему (из-за перенаправления) и т. Д. ...)

Так что без этих дополнительных ошибок я мог бы просто удалить аргумент LoginModel из контроллера Get Login, и он работал бы хорошо. Но так как я хочу передать пользовательские сообщения поверх проверки, мне нужен аргумент модели. Но, в свою очередь, это означает, что даже когда я загружаю страницу без чего-либо, на ней будет отображаться ошибка проверки (в данном случае требуется электронная почта).

Какие у меня варианты?

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Но так как я хочу передать пользовательские сообщения поверх проверки, мне нужен аргумент модели.

Вы на самом деле не. Вы можете просто использовать состояние модели для этого тоже. Несмотря на то, что ошибки проверки модели обычно устанавливаются автоматически структурой проверки, нет ничего плохого в добавлении собственных ошибок модели поверх этих.

Например, действие входа в систему POST может выглядеть следующим образом:

[HttpPost]
public async Task<IActionResult> Login(LoginModel model)
{
    if (!ModelState.IsValid)
        return View(model);

    var user = await _userManager.FindByEmailAsync(model.Email);
    if (user != null)
    {
        var result = await _signInManager.PasswordSignInAsync(user, model.Password, model.RememberMe);
        if (result.Succeeded)
            return RedirectToAction(nameof(HomeController.Index), "Home");
    }

    // add additional error message
    ModelState.AddModelError(string.Empty, "Login failed");
    return View(model);
}

Таким образом, вы не ограничены расширением модели представления сообщениями об искусственных ошибках только для отображения пользовательских ошибок модели.

0 голосов
/ 13 сентября 2018

Я нашел рабочее решение, но это может быть не самое чистое. Вместо того, чтобы помещать пользовательское сообщение об ошибке в модель, передайте его через ViewData следующим образом:

[HttpGet("login")]
[AllowAnonymous]
public IActionResult LoginGet(string errorMessage = null)
{
    ViewData["loginErrorMessage"] = errorMessage;
    return View();
}

[HttpPost("login")]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> LoginPost(LoginModel model)
{
    if (!ModelState.IsValid)
    {
        return View("Login", model);
    }
    ...
}

[HttpPost("login")]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Whatever(LoginModel model)
{
    var error = "The one time login link has expired";
    return RedirectToAction("Login", new {errorMessage = error};
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...