#c# #asp.net #validation #model-view-controller #razor
Вопрос:
Я знаю, что это было бы проще, если бы у меня были разные модели представления для входа и регистрации, однако, к сожалению, они должны быть в одной и той же модели представления. Это соответствующие методы в usercontroller
public async Task<IActionResult> Login([Bind("Email,Password")]UserViewModel m)
{
// call service to Authenticate User
var user = svc.Authenticate(m.Email, m.Password);
if (user == null)
{
ModelState.AddModelError("Email", "Invalid Login Credentials");
ModelState.AddModelError("Password", "Invalid Login Credentials");
return View(m);
}
// sign user in using cookie authentication to store principal
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
BuildClaimsPrincipal(user)
);
return RedirectToAction("Index","Home");
}
public IActionResult Register()
{
return View();
}
[HttpPost]
// add validate anti forgery token
[ValidateAntiForgeryToken]
public IActionResult Register([Bind("Name, Email, Password, PasswordConfirm, Role")]UserViewModel m)
{
// Q2
// attempt to retrieve a user by the viewmodel email address (call svc.GetUserByEmail(m.Email))
// var user = svc.GetUserByEmail(m.Email);
// // if user returned is not null then
// if(user != null)
// // add a modelstate error as email address must already be in use
// // see login action above for example of adding manual modelstate error
// {
// ModelState.AddModelError("Email", "Email Address Already In Use");
// return View(m);
// }
// endif
// if not valid model
if(!ModelState.IsValid)
{
return View(m);
}
// call service to register user
// Add alert indicating registration successful and redirect to login page
svc.Register(m.Name, m.Email, m.Password, m.Role);
Alert("Registration Successful", AlertType.info);
return RedirectToAction(nameof(Login));
}
[HttpPost]
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return RedirectToAction(nameof(Login));
}
[AcceptVerbs("GET","POST")]
public IActionResult VerifyEmail(string email)
{
if (svc.GetUserByEmail(email) != null)
{
return Json($"Email {email} is already in use.");
}
return Json(true);
}
Это модель пользователя
public class UserViewModel
{
// Q3 add validation attributes
[Required]
public string Name { get; set; }
[Required]
[EmailAddress]
[Remote(action: "VerifyEmail", controller: "User")]
public string Email { get; set; }
[Required]
public string Password { get; set; }
[Compare("Password", ErrorMessage = "Confirm Password doesn't match! Try again!")]
public string PasswordConfirm { get; set; }
[Display(Name = "Role")]
[Required(ErrorMessage = "{0} is required.")]
public Role Role { get; set; }
}
Поэтому, когда я регистрируюсь, если используется электронное письмо, оно показывает ошибку, и это здорово! Но на странице входа в систему написано, что электронная почта уже используется и никому не позволит войти в систему?
Есть ли у кого-нибудь решение при сохранении прежней модели?
Ответ №1:
Вы можете использовать заголовок ссылки на объект запроса. Добавьте эти строки в начале вашего метода проверки почты:
var referer = Request.Headers["Referer"];
if (referer.Count > 0 amp;amp; referer.ToString().Contains("Login"))
{
return Json(true);
}
Мы проверяем исходную страницу входящего запроса в заголовке, и если она присутствует и инициирована со страницы входа в систему, мы не будем продолжать.