Вопрос или проблема
У меня, как мне кажется, есть очень простая страница для восстановления пароля. Моя идея заключается в том, чтобы хранить 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. Давайте разберемся, как работает передача данных между представлениями и контроллерами, а также какова роль модели в этом процессе.
Понимание процесса передачи данных
-
Создание модели:
При каждом запросе к вашему контроллеру (например, когда пользователь отправляет форму) ASP.NET создает новый экземпляр моделиForgetPasswordModel
. Это означает, что если вы не сохраняете состояние между запросами, все свойства структуры модели будут вновь инициализированы по умолчанию. -
Передача данных обратно в представление:
Ваша модель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-запросе, что улучшит пользовательский опыт на вашем сайте.
Не забывайте, что любой подход имеет свои плюсы и минусы в контексте безопасности и сложности реализации, поэтому выбирайте тот, который наилучшим образом соответствует требованиям вашего приложения.