Я хочу реализовать удаленную проверку для регистрации, но не для входа в систему ASP.NET, так как это не позволит ни одному пользователю войти в систему

#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);
}
 

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