This is ASP.NET Razor Pages Project with ASP.NET Identity Registration Page (.NET 8).
Email checking (PageRemote) works fine, but only if the Email property is not a member of the Input class (automatically generated by ASP.NET Identity)
[BindProperty]
[Required]
[EmailAddress]
[Display(Name = "Email")]
[PageRemote(
ErrorMessage = "This email is already registered",
AdditionalFields = "__RequestVerificationToken",
HttpMethod = "post",
PageHandler = "CheckEmail"
)]
public string? Email { get; set; }
public JsonResult OnPostCheckEmail()
{
var valid = !_dbcontext.Accounts.ToList().Exists(p => p.Email.Equals(Email, StringComparison.CurrentCultureIgnoreCase));
return new JsonResult(valid);
}
Once you put this construction in a Input class, everything stops working.
[BindProperty]
public InputModel Input { get; set; }
public class InputModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
[PageRemote(
ErrorMessage = "This email is already registered",
AdditionalFields = "__RequestVerificationToken",
HttpMethod = "post",
PageHandler = "CheckEmail"
)]
public string? Email { get; set; }
}
public JsonResult OnPostCheckEmail()
{
var valid = !_dbcontext.Accounts.ToList().Exists(p => p.Email.Equals(Input.Email, StringComparison.CurrentCultureIgnoreCase));
return new JsonResult(valid);
}
What am I doing wrong?)
2
Answers
When you use a tag helper to generate an input for a nested class property, the
name
attribute is generated asNestedClassName.PropertyName
All fields listed in theAdditionalFields
property will be prefixed with the nested class name when they are posted, so in your case, the request verification token will be posted asInput.__RequestVerificationToken
. Consequently, the request verification token itself is not found, and request verification fails resulting in a 400 status code.Add a separate property to the PageModel –
Email
– for the remote validation, as in your working example, and on successful validation, assign the value to the nested property. Or write your own JavaScript to perform remote validation.In your view template:
Razor Pages remote validation requires the property to be validated must be a direct descendent of the PageModel class (i.e. not a property of a child property of the PageModel). And the
__RequestVerificationToken
is always on the root of the model.It will pass
Input.__RequestVerificationToken
to handler when[PageRemote]
is declared in theInputModel
, but there is no such element namedInput__RequestVerificationToken
, so the PageRemote request will always get http status code 400 which is why everthing stops working.So you can write a simple script to strip out the prefix for the request verification token.
NOTE: This script needs to be placed after jQuery, but before the validation libraries.
For the handler: