Проблема с совмещением страниц Login и Register в Identity Net Core из-за свойств [BindProperty] и [Required]
Появилась необходимость совместить 2 страницы Identity: Login и Register, поместив их на одной странице.
За основу была взята страница Login. В неё вписал функционал Register. После всех преобразований получилось следующее
Login.cshtml ...
<div class="form-container sign-up-container">
<form asp-route-returnUrl="@Model.ReturnUrl" asp-page-handler="register" method="post">
<h1>Регистрация</h1>
<span class="title-span">Заполните все указанные ниже поля</span>
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<input asp-for="RegisterVModel.Password" class="inputText form-control" required/>
<span class="floating-label">Пароль</span>
<span asp-validation-for="RegisterVModel.Password" class="text-danger"></span>
</div>
<div class="form-group">
<input asp-for="RegisterVModel.ConfirmPassword" class="inputText form-control" required/>
<span class="floating-label">Подтверждение пароля</span>
<span asp-validation-for="RegisterVModel.ConfirmPassword" class="text-danger"></span>
</div>
<div class="form-group">
<input asp-for="RegisterVModel.Email" class="inputText form-control" required/>
<span class="floating-label">Адрес ведомственной электронной почты</span>
<span asp-validation-for="RegisterVModel.Email" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Регистрация</button>
</form>
</div>
<div class="form-container sign-in-container">
<form asp-page-handler="login" method="post">
<h1>Выполнить вход</h1>
<span class="title-span">Укажите свой логин и пароль для входа</span>
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<input asp-for="LoginVModel.UserName" class="inputText form-control" required/>
<span class="floating-label">Имя пользователя</span>
<span asp-validation-for="LoginVModel.UserName" class="text-danger" style="font-size:7px"></span>
</div>
<div class="form-group">
<input asp-for="LoginVModel.Password" class="inputText form-control" required/>
<span class="floating-label">Пароль</span>
<span asp-validation-for="LoginVModel.Password" class="text-danger"></span>
</div>
<div class="checkbox">
<label asp-for="LoginVModel.RememberMe">
<input asp-for="LoginVModel.RememberMe" style="width: auto;"/>
@Html.DisplayNameFor(m => m.LoginVModel.RememberMe)
</label>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Войти</button>
</div>
<div class="form-group">
<p>
<a href="#">Забыли свой пароль?</a>
</p>
</div>
</form>
</div>
...
Login.cshtml.cs ...
[AllowAnonymous]
public class LoginModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly ILogger<LoginModel> _logger;
public LoginModel(SignInManager<IdentityUser> signInManager,
ILogger<LoginModel> logger,
UserManager<IdentityUser> userManager)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
}
[BindProperty]
public LoginViewModel LoginVModel { get; set; }
[BindProperty]
public RegisterViewModel RegisterVModel { get; set; }
public IList<AuthenticationScheme> ExternalLogins { get; set; }
public string ReturnUrl { get; set; }
[TempData]
public string ErrorMessage { get; set; }
public class LoginViewModel
{
//[Required(ErrorMessage = "Поле <b>{0}</b> обязательно для ввода")]
[Display(Name = "Имя пользователя", Prompt = "Имя пользователя")]
public string UserName { get; set; }
//[Required(ErrorMessage = "Поле <b>{0}</b> обязательно для ввода")]
[DataType(DataType.Password)]
[Display(Name = "Пароль", Prompt = "Пароль")]
public string Password { get; set; }
[Display(Name = "Запомнить меня?")]
public bool RememberMe { get; set; }
}
public class RegisterViewModel
{
//[Required(ErrorMessage = "Поле <b>{0}</b> обязательно для ввода")]
[StringLength(100, ErrorMessage = "Значение поля <b>{0}</b> должно содержать не менее <b>{2}</b> символов.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Пароль", Prompt = "Пароль")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Подтверждение пароля", Prompt = "Подтверждение пароля")]
[Compare("Password", ErrorMessage = "Пароль и его подтверждение не совпадают.")]
public string ConfirmPassword { get; set; }
//[Required(ErrorMessage = "Поле <b>{0}</b> обязательно для ввода")]
[Display(Name = "Адрес электронной почты", Prompt = "Адрес электронной почты")]
public string Email { get; set; }
}
public async Task OnGetLoginAsync(string returnUrl = null)
{
...
}
public async Task<IActionResult> OnPostLoginAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
...
}
return Page();
}
public async Task OnGetRegisterAsync(string returnUrl = null)
{
...
}
public async Task<IActionResult> OnPostRegisterAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
...
}
return Page();
}
}
...
Проблема возникает в том, что от пользователя требуется либо зарегистрироваться, либо авторизоваться. Но проблема в том, что [BindProperty]
[BindProperty]
public LoginViewModel LoginVModel { get; set; }
[BindProperty]
public RegisterViewModel RegisterVModel { get; set; }
проверяет обо класса и у полей, которых есть свойство [Required()]. Это приводит к тому, что пользователю нужно заполнять все поля в области регистрации и авторизации, у которых есть свойство [Required()], чтобы выполнить регистрацию или войти в систему. Если убрать [Required()], то всё работает, и валидация за счёт jquery.validate.js в Identity проходит. Но хотелось бы решить эту проблему так, чтобы и [Required()] можно было использовать. Как это сделать