MVC сбрасывает int до 0 при каждом отправлении.

Вопрос или проблема

У меня, как мне кажется, есть очень простая страница для восстановления пароля. Моя идея заключается в том, чтобы хранить int и увеличивать его, и если будет достигнут порог, модель будет сбойной. Что я не могу понять, так это почему мой int возвращается к 0 при каждом запросе.

Вот мой контроллер.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ForgetPassword(Models.Portal.ForgetPasswordModel forgetPasswordModel)
{
    if (ModelState.IsValid)
    {
        forgetPasswordModel.isEmail = Helper.Validation.IsValiEmailAddress(forgetPasswordModel.AccountName);
        forgetPasswordModel.ForgetAttempt = forgetPasswordModel.ForgetAttempt + 1;
        if (forgetPasswordModel.ForgetPasswordReset == Models.Portal.ForgetPasswordReset.Success)
        {
            return RedirectToAction("ResetPassword", "Portal", new Models.Portal.ResetPasswordModel());
        }
        else
        {
            ViewBag.ShowForgetPasswordError = true;
        }
    }
    return View(forgetPasswordModel);
}

Вот мой вид

@model AuthFrameworkMVCSite.Models.Portal.ForgetPasswordModel
@{
    ViewBag.Title = "View";
    Layout = "~/Views/Shared/_LayoutAuthFramework.cshtml";
}

@using (Html.BeginForm("ForgetPassword", "Portal", FormMethod.Post))
{
    @Html.AntiForgeryToken()
    <h2>Имя пользователя/Электронная почта</h2>
    @Html.TextBoxFor(m => m.AccountName)
    <br />
    <br />
    <input type="submit" value="Восстановить пароль" />
    if (ViewBag.ShowForgetPasswordError == true)
    {
        <div class="col-lg-offset-3 col-lg-6">
            Что-то пошло не так. Пожалуйста, попробуйте снова.
        </div>
    }
}
<div id="loader" style="display:none">
    Загрузка...
</div>

Вот моя модель

public class ForgetPasswordModel
{
    [Required]
    public string AccountName { get; set; }
    public bool isEmail { get; set; }
    public ForgetPasswordReset ForgetPasswordReset { get; set; }

    [Range(0, 5)]
    public int ForgetAttempt { get; set; }
}
public enum ForgetPasswordReset
{
    Failure,
    Success
}

Любая помощь будет оценена. Я возвращаю модель после увеличения значения.

Ответ или решение

Проблема сброса переменной int до 0 при каждом POST-запросе на странице "Забыли пароль"

Ваша проблема с тем, что переменная ForgetAttempt сбрасывается до 0 при каждом POST-запросе, связана с особенностями жизненного цикла модели в ASP.NET MVC. Давайте разберемся, как работает передача данных между представлениями и контроллерами, а также какова роль модели в этом процессе.

Понимание процесса передачи данных

  1. Создание модели:
    При каждом запросе к вашему контроллеру (например, когда пользователь отправляет форму) ASP.NET создает новый экземпляр модели ForgetPasswordModel. Это означает, что если вы не сохраняете состояние между запросами, все свойства структуры модели будут вновь инициализированы по умолчанию.

  2. Передача данных обратно в представление:
    Ваша модель ForgetPasswordModel имеет свойство ForgetAttempt, которое инкапсулирует количество попыток сброса пароля. При каждом новом посте происходит создание новой модели, в которой это свойство остается равным 0, поскольку значение не сохраняется.

Как решить проблему?

Для сохранения значения переменной ForgetAttempt между пост-запросами вам нужно использовать временные или постоянные механизмы хранения состояния. Есть несколько способов сделать это:

1. Использование сессии

Сессия позволяет хранить данные между запросами. Вы можете сохранить количество попыток в переменной сессии.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ForgetPassword(Models.Portal.ForgetPasswordModel forgetPasswordModel)
{
    if (Session["ForgetAttempt"] == null)
    {
        Session["ForgetAttempt"] = 0;
    }

    // Увеличиваем количество попыток
    forgetPasswordModel.ForgetAttempt = (int)Session["ForgetAttempt"] + 1;
    Session["ForgetAttempt"] = forgetPasswordModel.ForgetAttempt;

    if (ModelState.IsValid)
    {
        forgetPasswordModel.isEmail = Helper.Validation.IsValiEmailAddress(forgetPasswordModel.AccountName);
        if (forgetPasswordModel.ForgetPasswordReset == Models.Portal.ForgetPasswordReset.Success)
        {
            return RedirectToAction("ResetPassword", "Portal", new Models.Portal.ResetPasswordModel());
        }
        else
        {
            ViewBag.ShowForgetPasswordError = true;
        }
    }

    return View(forgetPasswordModel);
}

С помощью этого подхода значение будет сохраняться между запросами, и ForgetAttempt не будет сбрасываться.

2. Использование формата Cookies

Если вы хотите, чтобы данные были доступны даже после закрытия браузера, можно рассмотреть использование Cookie:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ForgetPassword(Models.Portal.ForgetPasswordModel forgetPasswordModel)
{
    int attempts = 0;
    if (Request.Cookies["ForgetAttempt"] != null)
    {
        int.TryParse(Request.Cookies["ForgetAttempt"].Value, out attempts);
    }

    attempts++;
    HttpCookie cookie = new HttpCookie("ForgetAttempt");
    cookie.Value = attempts.ToString();
    cookie.Expires = DateTime.Now.AddMinutes(30); // Установите время жизни cookie
    Response.Cookies.Add(cookie);

    forgetPasswordModel.ForgetAttempt = attempts;

    if (ModelState.IsValid)
    {
        forgetPasswordModel.isEmail = Helper.Validation.IsValiEmailAddress(forgetPasswordModel.AccountName);
        if (forgetPasswordModel.ForgetPasswordReset == Models.Portal.ForgetPasswordReset.Success)
        {
            return RedirectToAction("ResetPassword", "Portal", new Models.Portal.ResetPasswordModel());
        }
        else
        {
            ViewBag.ShowForgetPasswordError = true;
        }
    }

    return View(forgetPasswordModel);
}

Заключение

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

Таким образом, вы сможете избежать сброса значения инкрементируемой переменной ForgetAttempt при каждом новом POST-запросе, что улучшит пользовательский опыт на вашем сайте.

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

Оцените материал
Добавить комментарий

Капча загружается...