I'm trying to make a simple login form in ASP.NET Core Razor Pages, which has an email address field, a password field, a login button and a forgot-password button.
I want to utilize the inbuilt client-side and server-side validation on the text fields, such that the email field is required for both button submissions, but the password field is only required for login button submission.
Decorating the model properties with a [Required]
attribute makes them mandatory for all form post handlers, where-as I'm looking for some way to have conditional model binding, either programmatically or through an attribute on model properties or handler method parameters.
Is it possible to define conditional model binding to achieve this, or is there a clean & simple alternative?
You can achieve that by using custom required attributes. For example, different buttons will trigger different handlers:
<div>
<button type="submit" asp-page-handler="Login">Login</button>
<button type="submit" asp-page-handler="ChangePassword">login</button>
</div>
Register IActionContextAccessor
:
services.AddHttpContextAccessor();
Custom required attributed :
public class MyRequiredAttribute : RequiredAttribute
{
private string _handlerName;
public MyRequiredAttribute(string handlerName)
{
_handlerName = handlerName;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var httpContext = validationContext.GetRequiredService<IHttpContextAccessor>().HttpContext;
var handlerName = httpContext.Request.Query["handler"].ToString();
if (handlerName.ToLower().Equals(_handlerName.ToLower()))
{
return base.IsValid(value, validationContext);
}
else
{
return ValidationResult.Success;
}
}
}
Apply to your property:
[BindProperty]
[Required]
[MinLength(6)]
public string UserName { get; set; }
[BindProperty]
[MyRequiredAttribute("Login"), MinLength(6)]
public string Password { get; set; }