Remote validation in ASP.NET (Core) relies on
Unobtrusive AJAX, so you will need to install that first. The
easiest way to do this is via LibMan. Right click on the lib folder in
wwwroot, choose Add » Client-side Library, and then choose jsdelivr as
the source, and type in jquery-ajax-unobtrusive
, You should see it
appear in the list of packages available:
A common use case for remote validation is to check whether a user name
or email address already exists in the database, if your business rules
do not allow duplicates. To better focus on applying remote
validation, this demo features a form with just the one input. Here is an example PageModel class
that includes a property named Email
:
public class RemoteValidationTestModel : PageModel { [BindProperty] public string Email { get; set; } public void OnGet() { } }
And here is a form that includes an input for the Email
property, and a
validation tag helper.
<form method="post"> <input asp-for="Email" /> <span asp-validation-for="Email"></span><br> <input type="submit"/> </form>
As I mentioned before, remote validation relies on unobtrusive AJAX,
so you need to reference jQuery, Unobtrusive AJAX and the
Unobtrusive Validation library in the same page as the form. How you
do that depends on where else in the application you might need
these libraries, but the code below illustrates how to include all
of them in a single page within a @section
block:
@section scripts{ <script src="~/lib/jquery/dist/jquery.min.js"></script> <partial name="_ValidationScriptsPartial" /> <script src="~/lib/jquery-ajax-unobtrusive/dist/jquery.unobtrusive-ajax.min.js"></script> }
Now you need to add a
handler method to perform the validation. The handler method itself
must provide a JSON response indicating whether validation succeeded or
failed (true
or false
). The following example
uses a named handler which is added to the same PageModel as before:
public JsonResult OnPostCheckEmail() { var existingEmails = new[] { "[email protected]", "[email protected]", "[email protected]" }; var valid = !existingEmails.Contains(Email); return new JsonResult(valid); }
In the real world, this handler would compare the submitted email
address to database records, but in demo land, it checks to see if the
email is one of three hard coded values, returning true
if
not (i.e. the email is a valid value) and false
if it is a
duplicate.
The final step is to apply the new remote validation attribute, which is
called a PageRemoteAttribute
. It shares many of the same
properties as the MVC RemoteAttribute
:
Property | Description |
---|---|
AdditionalFields | A comma separated list of additional fields that should be included in the validation request |
ErrorMessage | The error message to be displayed in the event of validation failure |
ErrorMessageResourceName | The name of the Resource where the error message is stored, if one is used |
ErrorMessageResourceType | The type of the resource used to store the error message |
HttpMethod | The HTTP verb to be used for the request
(GET or POST ). Default is GET |
The PageRemote
attribute also includes a couple of other properties:
PageName
and PageHandler
. The PageName
is the name of the page that the request should be sent to, and the
PageHandler
is the name of the handler method that should be invoked. In both cases, if they are omitted, "ambient values" will be used i.e. the current page, and whichever conventionally named handler method that responds to the HTTP verb that is used.
The PageRemote
attribute is applied to the property that needs
validating. In this example, the configuration of the PageRemote
attribute
is as follows:
[PageRemote( ErrorMessage ="!!! Duplicate Email Address !!!", AdditionalFields = "__RequestVerificationToken", HttpMethod ="post", PageHandler ="CheckEmail" )] [BindProperty] public string Email { get; set; }
The handler method that performs validation is set up to respond to
POST
requests. It is in the same page as the property to be validated
so the PageName
is omitted. The AdditionalFields
property is set to include the hidden
request verification token generated by the form tag helper. If you
don't include this field for POST
requests, the
request will fail with a 400 Bad Request status code.
And that's all there is to it. If you run the page and enter one of the hardcoded email addresses, the change event fires the AJAX request and validates the value:
Summary
The PageRemote
attribute was introduced in ASP.NET Core 3.0
to no fanfare whatsoever (until now). It's a nice addition, in that it
removes the need for controllers in your Razor Pages application for
performing remote validation simply and effectively.