Client and Server validation in ASP.NET MVC

facebooktwittergoogle_plusredditpinterestlinkedinmail



In ASP.NET MVC we have data annotation to validate input. There are lots of predefined attribute available in the MVC like [Required]. In this article I will show you the custom client and server side validation in ASP.NET MVC using data annotation.


Server Side Validation in ASP.NET MVC.

I have 3 fields. Here the amount should be greater than the balance. To achieve this, first create an MVC application. See the following demo. Create a custom attribute that derived from ValidationAttribute
Attribute

public class ValidAmountAttribute: ValidationAttribute
    {
        string compareProp;
        public ValidAmountAttribute(string prop, string errorMsg)
            : base(errorMsg)
        {
            this.compareProp = prop;
        }
        public override string FormatErrorMessage(string name)
        {
 
            return string.Format(ErrorMessageString, name, compareProp);
        }
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            ValidationResult validationResult = ValidationResult.Success;
            if (value!= null)
            {
 
                 var comparteprop = validationContext.ObjectType.GetProperty(this.compareProp);
                 decimal referenceProperty = (decimal)comparteprop.GetValue(validationContext.ObjectInstance, null);
                 if (Convert.ToDecimal(value) > referenceProperty)
                {
                    validationResult = new ValidationResult(ErrorMessageString);
 
                }
            }
            return validationResult;
        }
    }

This attribute allows 2 parameters. First is the property name to be compared and the second is an error message to be displayed.
Model

 public class PaymentModel
    {
       //model
        public int AccountNumber { get; set; }
        public decimal Balance { get; set; }
        [Required]
        [ValidAmount("Balance","Amount must be greater than balance.")]
        public decimal? Amount { get; set; }
    }

Here I have applied the ValidAmount Attribute on Amount field.
Controller

 public class HomeController : Controller
    {
        //controller 
 
        [HttpGet]
        public ActionResult Index()
        {
            PaymentModel model = new PaymentModel();
            model.AccountNumber = 123456779;
            model.Balance = 56;
            return View(model);
        }
 
        [HttpPost]
        public ActionResult Index(PaymentModel model)
        {
            if (ModelState.IsValid)
            {
 
            }
            return View(model);
        }
 
    }

View

@model Test.Validation.Models.PaymentModel
@{
    ViewBag.Title = "Home Page";
}
 
<script src="~/scripts/jquery-1.10.2.js"></script>
<script src="~/scripts/jquery.validate.min.js"></script>
<script src="~/scripts/jquery.validate.unobtrusive.min.js"></script>
@using (Html.BeginForm())
{
    @Html.HiddenFor(p=>p.AccountNumber)
    @Html.HiddenFor(p => p.Balance)
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Payment</legend>
 
        <div class="editor-label">
            @Html.LabelFor(model => model.AccountNumber)
        </div>
        <div class="editor-field">
           @Model.AccountNumber
        </div>
 
        <div class="editor-label">
            @Html.LabelFor(model => model.Balance)
        </div>
        <div class="editor-field">
            @Model.Balance
        </div>
 
        <div class="editor-label">
            @Html.LabelFor(model => model.Amount)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Amount)
            @Html.ValidationMessageFor(model => model.Amount)
        </div>
 
        <p>
            <input type="submit" value="Pay" />
        </p>
    </fieldset>
}

See the result.

validation in ASP.NET MVC

Here you can see the error message throwing from server side. To improve the performance we need client side validation.

Client Side Validation in ASP.NET MVC


We have IClientValidatable interface to enable client side validation in MVC.See the following implementation of IClientValidatable in our existing attribute.

 public class ValidAmountAttribute : ValidationAttribute, IClientValidatable
    {
        string compareProp;
        decimal referenceProperty;
        public ValidAmountAttribute(string compareProp, string errorMsg)
            : base(errorMsg)
        {
            this.compareProp = compareProp;
        }
        public override string FormatErrorMessage(string name)
        {
 
            return string.Format(ErrorMessageString, name, compareProp);
        }
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            ValidationResult validationResult = ValidationResult.Success;
            if (value!= null)
            {
 
                 var comparteprop = validationContext.ObjectType.GetProperty(this.compareProp);
                 referenceProperty = (decimal)comparteprop.GetValue(validationContext.ObjectInstance, null);
                 if (Convert.ToDecimal(value) > referenceProperty)
                {
                    validationResult = new ValidationResult(ErrorMessageString);
 
                }
            }
            return validationResult;
        }
 
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            ModelClientValidationRule validAmtRule = new ModelClientValidationRule();
            validAmtRule.ErrorMessage = ErrorMessageString;
            validAmtRule.ValidationType = "validamt";
            validAmtRule.ValidationParameters.Add("compareprop", referenceProperty);
            yield return validAmtRule; 
        }
    }

In the above code we have set the validation rule and parameters. Write the following script on our view to validate.

$.validator.addMethod("validamt",function(value,element,params)
{
 
    if (parseInt(value) > parseInt(params)) {
        return false;
    } else {
        return true;
    }
 
});
 
$.validator.unobtrusive.adapters.addSingleVal("validamt", "compareprop");
<input class="text-box single-line" data-val="true" data-val-number="The field Amount must be a number." data-val-required="The Amount field is required." data-val-validamt="Amount must be greater than balance." data-val-validamt-compareprop="0" id="Amount" name="Amount" type="text" value="">
The following two tabs change content below.

Tom Mohan

Tom Mohan is a technologist who loves to code and build. He enjoys working on Microsoft Technologies. Tom specializes in ASP.NET MVC, Web API , Azure, C# ,WPF, SQL etc and holds a Bachelor engineering degree in Computer Science. Certification : MCSD , MCTS