Create a Custom Remote Attribute in MVC


In this example we will create a custom attribute that will validate the customer email id and mobile number uniqueness while inserting a new customer in the database. There are the following Customer table scripts that we will work on in this article.


  1. CREATE TABLE [dbo].[tblEmployee](  
  2.     [EmployeeId] [int] IDENTITY(1,1) NOT NULL,  
  3.     [Name] [nvarchar](50) NOT NULL,  
  4.     [Gender] [nvarchar](10) NULL,  
  5.     [City] [nvarchar](50) NOT NULL,  
  6.     [EmailId] [nvarchar](50) NOT NULL,  
  7.     [MobileNo] [nvarchar](15) NOT NULL,  
  9. (  
  10.     [EmployeeId] ASC  
  12. ON [PRIMARY]  
I am inserting the following sample data:
  1. INSERT INTO [manishDB].[dbo].[tblEmployee]  
  2.            ([Name]  
  3.            ,[Gender]  
  4.            ,[City]  
  5.            ,[EmailId]  
  6.            ,[MobileNo])  
  7.      VALUES  
  8.            ('Manish'  
  9.            ,' Male'  
  10.            ,'Hyderabad'  
  11.            ,'[email protected]'  
  12.            ,'9052390048')  
  13. GO  
  14. INSERT INTO [manishDB].[dbo].[tblEmployee]  
  15.            ([Name]  
  16.            ,[Gender]  
  17.            ,[City]  
  18.            ,[EmailId]  
  19.            ,[MobileNo])  
  20.      VALUES  
  21.            ('Venkat'  
  22.            ,‘Male'  
  23.            ,'Hyderabad'  
  24.            ,'[email protected]'  
  25.            ,'9452390048')  


Use the following procedure and create a remote custom attribute in MVC.

Step 1

Now open Visual Studio and go to "File" -> "New" -> "Project..." and under the web tab select ASP.NET web application and provide a meaningful name. In this case I am giving “CustomRemoteAttributeDemo” and click on the Ok button.


Step 2

Select MVC from the template tab and click on OK.

mvc template

Step 3

By default a MVC 5 project with some default code appears in Solution Explorer. Delete that if you want or leave it as it is. Now go to the Models folder and right-click on that then select add and select ADO.NET Entity Data Model and provide a meaningful name say EmployeeDb and click Ok.

entity data model

Step 4

Select "EF Designer from database" in the Entity Data Model Wizard then click "Next". Create a connection string and provide a meaningful name such as “EmployeeDbContext” and click "Next".

EF designer

Step 5

Select the tblEmployee table and in Namespace write the Models as namespace and click on "Finish".

database objects

Step 6

Now our tblEmployee entity is ready. Change the name to Employee and build the project once so that all the code compiles correctly.

employee table

Step 7

Now go to the controller folder and right-click on it and select Add then select New Scaffolded Items as follows.


Step 8

The following dialog box appears. Select "MVC5 controller with views using Entity Framework" and click "Add".

add scaffold

Step 9

Then for "Model Class" select Employee and for the "Data context class" select "EmployeeDbContext" and leave the rest as defaults and click on "Add".

add controller

Note: Remote attribute only works when JavaScript is enabled. If the end user disables JavaScript on his/her machine then the validation does not work. This is because RemoteAttribute requires JavaScript to make an asynchronous AJAX call to the server-side validation method. As a result, the user will be able to submit the form, bypassing the validation in place. This's why it is always important to have server-side validation.

Step 10

By default the controller and related view has been generated by MVC. Run the project and navigate to create the action method. Here if we insert the same mobile number and email id then it is also accepting that we need to remove by creating a custom attributes. The custom attribute will be used in the entire project so it will be best if we place it in a separate folder called common. Create a common folder and one class says “CustomRemoteAttribute”(you can give it a meaningful name) inside that folder.

For creating a remote attributes in MVC we need to inherit the RemoteAttribute class with it available inside the using System.Web.Mvc; namespace. So do this first like:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Mvc;  
  7. namespace CustomRemoteAttributeDemo.Common  
  8. {  
  9.     public class CustomRemoteAttribute : RemoteAttribute  
  10.     {  
  12.     }  
  13. }  


Step 11

Then we need to override the IsValid function of class RemoteAttribute. The best way to override any function is to just type the override keyword then you will find the list of all the functions that can be overriden.

override method

In this case we need to override the IsValide method that accepts two parameters. Just click on that and you will get the following code and delete that return code and implement the logic there.


  1. protected override System.ComponentModel.DataAnnotations.ValidationResult IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext)  
  2.         {  
  3.             return base.IsValid(value, validationContext);  
  4.         }     


Step 12

Then we need to write some reflection code so first add the namespace "using System.Reflection;" and start writing the following code inside the IsValide() methord.


  1. // Get the controller Name where the required validation function is  
  2.             Type controller = Assembly.GetExecutingAssembly().GetTypes()  
  3.                 .FirstOrDefault(type => type.Name.ToLower() == string.Format("{0}Controller",  
  4.                     this.RouteData["controller"].ToString()).ToLower());  


Step 13

Then check to ensure the controller is available. If the controller is available then find the method that will check the database with a mobile number or email id and return true or false as a JOSN result. Here in this case create the following two methods to determine email id and mobile number availability. Create both methods inside the Employees controller.


  1. public JsonResult IsMobileNumberAvailable(string MobileNumber)  
  2. {  
  3.     return Json(!db.Employees.Any(x => x.MobileNo == MobileNumber),  
  4.                                          JsonRequestBehavior.AllowGet);  
  5. }  
  6. public JsonResult IsEmailIdAvailable(string EmailId)  
  7. {  
  8.     return Json(!db.Employees.Any(x => x.EmailId == EmailId),  
  9.                                          JsonRequestBehavior.AllowGet);  
  10. }  


Step 14

Now go to IsValide() inside the common folder and write the following code.

isvalid method


  1. protected override ValidationResult IsValid(object value, ValidationContext validationContext)  
  2.         {  
  4.             // Get the controller using reflection  
  5.             Type controller = Assembly.GetExecutingAssembly().GetTypes()  
  6.                 .FirstOrDefault(type => type.Name.ToLower() == string.Format("{0}Controller",  
  7.                     this.RouteData["controller"].ToString()).ToLower());  
  8.             if (controller != null)  
  9.             {  
  10.                 // Get the action method that has validation logic  
  11.                 MethodInfo action = controller.GetMethods()  
  12.                     .FirstOrDefault(method => method.Name.ToLower() ==  
  13.                         this.RouteData["action"].ToString().ToLower());  
  14.                 if (action != null)  
  15.                 {  
  16.                     // Create an instance of the controller class  
  17.                     object instance = Activator.CreateInstance(controller);  
  18.                     // Invoke the action method that has validation logic  
  19.                     object response = action.Invoke(instance, new object[] { value });  
  20.                     if (response is JsonResult)  
  21.                     {  
  22.                         object jsonData = ((JsonResult)response).Data;  
  23.                         if (jsonData is bool)  
  24.                         {  
  25.                             return (bool)jsonData ? ValidationResult.Success :  
  26.                                 new ValidationResult(this.ErrorMessage);  
  27.                         }  
  28.                     }  
  29.                 }  
  30.             }              
  31.              return new ValidationResult(base.ErrorMessageString);  
  32.         }  


Step 15

Now create the following constructor to set the error message and access the server-side and client-side response.


  1. public CustomRemoteAttribute(string routeName)  
  2.     : base(routeName)  
  3. {  
  4. }  
  6. public CustomRemoteAttribute(string action, string controller)  
  7.     : base(action, controller)  
  8. {  
  9. }  
  11. public CustomRemoteAttribute(string action, string controller,   
  12.     string areaName) : base(action, controller, areaName)  
  13. {  
  14. }  


Step 16

Build the project and now we need to apply DataAnnotations validation to an employee table, For that create a class EmployeeMetadata and apply the validation like the following.


  1. [MetadataType(typeof(EmployeeMetadata))]  
  2.     public partial class Employee  
  3.     {  
  5.     }  
  6.     public class EmployeeMetadata  
  7.     {  
  8.         [CustomRemoteAttribute("IsEmailIdAvailable""Employees",  
  9.         ErrorMessage = "Email Id already in use")]  
  10.         public string EmailId { getset; }  
  11.          [CustomRemoteAttribute("IsMobileNumberAvailable""Employees",  
  12.         ErrorMessage = "Mobile Number already in use")]  
  13.         public string MobileNo { getset; }  
  14.     }  


Here we need to add the reference "using CustomRemoteAttributeDemo.Common;" if your project name and class name are different then add that class reference.

That's it. Run the project and navigate to create a view and try to insert the duplicate email id then you will get the following error.

create employee


In this illustration you came to understand how to create custom remote attributes in MVC. Download the sample code for a better understanding. Thanks. I would like to get feedback from my readers. Please post your feedback, question, or comments about this article.

Up Next
    Ebook Download
    View all
    View all