Using the ‘Remote’ Attribute for Async Validation in ASP.NET MVC
Validation is an integral part of any input process in any computer software. As the saying goes ‘never trust anything the user gives you’. On the web, there are various ways of validating user input, some happen on the web-browser itself, some happen on the server after a user submits a form of data.
Today we will see how we can use the ‘Remote’ attribute to enhance the default Registration page that comes with ASP.NET MVC4 Internet template. You can adapt it for validating any text on the server side.
Use Case for Async Server-Side Validation
Let’s start off by creating an ASP.NET MVC application (I am using MVC 4RC here, but you could use MVC3 with .NET 3.5 SP1 too).
Step 1: Select the ‘Internet Application’ Template. This adds the AccountController and related Account related Views.
Step 3: Run the Application and click on Register on the top right corner.
Step 4: Register using valid registration details
Step 5: Once registered, log out and go to the Registration page again. Provide the same username as you provided earlier, put in all other details correctly and hit Submit. System comes back with an error saying User already exists.
The User in this case was warned of an issue after they hit Submit. It would be really nice if the User were warned of this issue as soon as they entered the User name. How can the User Name be validated? It is definitely not a client side validation as the list of existing users is only available on the server. For these kinds of scenarios we use the ‘Remote’ attribute for firing a server side Ajax call and doing the validation on the server side, keeping the existing form intact.
Setting up the Remote Attribute
To add the Async validation functionality we need to decorate our Model with an Attribute called ‘Remote’ and specify the Controller and Action method that will handle the Async request. This is done as follows
Step 1: Open the AccountModels.cs and navigate to the ‘RegisterModels’ class. On the UserName property, add the Remote attribute as follows. The ‘VerifyUserExists’ is the Action method on the ‘Account’ controller. We could specify a named parameter in the Remote attribute as ErrorMessage=’User Already Exists’, but we want to reuse the same message as the server side validation. So instead of duplicating text, we will retrieve it appropriately in the Action method.
Step 2: Open the AccountController.cs and add a Method VerifyUserExists. This returns a JsonResult. Decorate the method with AllowAnonymous because we want to access this method at the time of Registration, which is done Anonymously.
Step 3: In the VerifyUserExists method, check for the UserName using the Membership provider. If user already exists, return the same error message that is returned on Server Side validation. If the user does not exist return true.
The Unobtrusive jQuery validator will treat any non-boolean value as false. So if no explicit ErrorMessage is provided, it will display the value that is returned. In our case we are returning the error message that we want to display.
Step 4: Open the Register.cshtml. The form uses a ValidationSummary helper to show a summary of all errors on server side submits. However we want to show the validation result immediately. So we add a @Html.ValidationMessageFor(m => m.UserName) to the UserName field. So if the Remote validator comes back with error it is shown immediately next to the field.
That’s it, we are all set with our Async validation for UserName. Run the application and try to create another user with the same name as the existing user. Notice how the error message comes up almost instantly. Warning the user before too many other elements have been populated.
Remote attributes provide an easy way for doing server side validations where client-side validation is not possible and we want to provide an Ajaxified experience to the end-user that does not involve a lot of full page Postbacks.
ASP.NET MVCs validation framework is pretty extensive and has other extensibility points like custom Client Side validators. We will explore these in future, but for mandatory server side validations Remote attributes sit in a nice middle-ground of doing server side validations and maintaining near-client-side-validation interactive-ness.
Repository at - https://github.com/devcurry/RemoteValidationAttribute