ASP.NET Core Client-Side and Remote Validation

ASP.NET Core Client-Side and Remote Validation

In this article, I will discuss ASP.NET Core Remote and Client-Side Validation. Please read our previous article discussing How to Redirect to ReturnUrl After Login in ASP.NET Core.

Server-Side Validation in ASP.NET Core

We have already discussed how to implement Client-Side and Server-Side Validations in ASP.NET Core in our ASP.NET Core MVC Validations Tutorials. The Server-Side Validation in ASP.NET Core Application is implemented using Data Annotation Validation Attributes such as Required, StringLength, etc.

Let us understand this with an example. In our application, we use the following RegisterViewModel class to register a new user using ASP.NET Core Identity. Here, you can see we are using Required, EmailAddress, Compare, etc. Validation Attributes.

using System.ComponentModel.DataAnnotations;
namespace ASPNETCoreIdentityDemo.Models
{
    public class RegisterViewModel
    {
        [Required]
        [EmailAddress]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "Password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
    }
}

Now, run the application and try to register a new user without filling in any information, and you should get the following error message as expected as shown in the below image.

ASP.NET Core Client-Side and Remote Validation

Server-side validations are done on the server, so a round trip exists between the Client Browser and the Web Server. The request has to be sent over the network to the web server for processing. If the network is slow or the server is busy processing other requests, the end user may have to wait a few seconds, which also increases the load on the server.

This validation can also be performed on the client side itself, which means there is no round trip to the server, no waiting time, the client has instant feedback, and the load on the web server is also greatly reduced.

How do you enable client-side validation in ASP.NET Core MVC?

To enable Client-Side Validation in ASP.NET Core MVC Application, we need to include the necessary JavaScript files. These files can be added via CDNs or local files. For example, include them via CDNs in your _Layout.cshtml file as follows:

<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<!-- jQuery Validation Plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.2/jquery.validate.min.js"></script>
<!-- jQuery Unobtrusive Validation (to bridge ASP.NET Core MVC validation with jQuery Validate) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"></script>

You can also add the following files to your _Layout.cshtml to enable client-side validation using local files. The order is also important, so please include them in the following order.

<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

The order in which the script files are referenced is also important. jquery.validate is dependent on jquery, and jquery.validate.unobtrusive is dependent on jquery.validate, so they should be referenced in the above order. Otherwise, client-side validation will not work as expected.

So, open the _Layout.cshtml file, copy and paste the following code. Here, we are adding the javascript local file to enable client-side validations.

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - ASPNETCoreIdentityDemo</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/ASPNETCoreIdentityDemo.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container-fluid">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                       
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>

                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="SecureMethod">Secure</a>
                        </li>

                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="NonSecureMethod">Non Secure</a>
                        </li>
                    </ul>
                    <ul class="navbar-nav ml-auto">
                        @*If the user is signed-in display Logout link*@
                        @if (SignInManager.IsSignedIn(User))
                        {
                            <li class="nav-item">
                                <form method="post" asp-controller="account" asp-action="logout">
                                    <button type="submit" style="width:auto"
                                            class="nav-link btn btn-link py-0">
                                        Logout @User?.Identity?.Name
                                    </button>
                                </form>
                            </li>
                        }
                        else
                        {
                            <li class="nav-item">
                                <a class="nav-link" asp-controller="account" asp-action="register">
                                    Register
                                </a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" asp-controller="account" asp-action="login">
                                    Login
                                </a>
                            </li>
                        }
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2023 - ASPNETCoreIdentityDemo - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
    <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @await RenderSectionAsync("Scripts", required: false)

</body>
</html>

With the above changes in place, client-side validation is enabled, and you will see the error messages without making a round trip to the server.

What is Remote Validation in ASP.NET Core?

Remote Validation in ASP.NET Core is a feature that allows us to perform server-side validation asynchronously from the client side. It allows a controller action method to be called using a client-side script, which is useful when calling a server-side method without a full-page postback.

So, this is useful when we need to validate input filed against server-side data or logic that cannot be performed on the client side. For instance, checking if a username or email address is already in use typically requires a database lookup, which can only be done on the server.

Example to Understand Remote Validation in ASP.NET Core

Let us understand the Remote Validation in ASP.NET Core MVC Application with an example. Now, when we register a new user with an existing email, we will get the following error message only when we submit the Register button:

Example to Understand Remote Validation in ASP.NET Core

Checking if another user has already taken the provided email can only be done on the server. At this point, when we click on the Register button, it will make a full-page post back to the server. So, instead of making a full-page post back to the server, we can use Remote Validation, which can asynchronously call the server to check whether the email has already been taken. Let us proceed and see how we can implement this in ASP.NET Core.

Creating the Validation Action:

We need to create an action method that will be called for validation. This action method should return a JSON result indicating whether the validation is successful or not. So, please add the following IsEmailAvailable method in the Account Controller. This method should respond to both HTTP GET and POST, which is why we specified HTTP verbs (HttpPost and HttpGet). The FindByEmailAsync() method of the User Manager class is used to find a user based on their email address.

[AllowAnonymous]
[HttpPost]
[HttpGet]
public async Task<IActionResult> IsEmailAvailable(string Email)
{
    //Check If the Email Id is Already in the Database
    var user = await userManager.FindByEmailAsync(Email);

    if (user == null)
    {
        return Json(true);
    }
    else
    {
        return Json($"Email {Email} is already in use.");
    }
}

An AJAX request is issued to this method. If this method returns true, validation succeeds. Otherwise, validation fails, and the form cannot be submitted. The parameter name Email must match the field name on the view. If they don’t match, the model binder will not be able to bind the value with the parameter, and validation will not work as expected.

Apply Remote Attribute:

Next, we need to apply the Remote attribute to the property we want to validate. To validate the Email property with Remote Validation, please modify the RegisterViewModel as follows. As you can see, we have applied the Remote Data Annotation Attribute with the Email Property and specified the controller and action name.

using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
namespace ASPNETCoreIdentityDemo.Models
{
    public class RegisterViewModel
    {
        [Required]
        [EmailAddress]
        [Remote(action:"IsEmailAvailable", controller: "Account")]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "Password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
    }
}

With the above changes in place, run the application, click the Register link, and give an existing email ID. You will immediately see the error message, as shown in the below image:

Client Side and Remote Validation in ASP.NET Core

In the next article, I will discuss Customizing AspNetUsers Table in ASP.NET Core Identity. In this article, I explain Client-Side and Remote Validation in ASP.NET Core MVC Application. I hope you enjoy this Client Side and Remote Validation in ASP.NET Core article.

1 thought on “ASP.NET Core Client-Side and Remote Validation”

Leave a Reply

Your email address will not be published. Required fields are marked *