Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

client-side validation in custom validation attribute - asp.net mvc 4

I have followed some articles and tutorials over the internet in order to create a custom validation attribute that also supports client-side validation in an asp.net mvc 4 website. This is what i have until now:

RequiredIfAttribute.cs

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] //Added public class RequiredIfAttribute : ValidationAttribute, IClientValidatable {     private readonly string condition;     private string propertyName; //Added      public RequiredIfAttribute(string condition)     {         this.condition = condition;         this.propertyName = propertyName; //Added     }      protected override ValidationResult IsValid(object value, ValidationContext validationContext)     {         PropertyInfo propertyInfo = validationContext.ObjectType.GetProperty(this.propertyName); //Added         Delegate conditionFunction = CreateExpression(validationContext.ObjectType, _condition);         bool conditionMet = (bool)conditionFunction.DynamicInvoke(validationContext.ObjectInstance);          if (conditionMet)         {             if (value == null)             {                 return new ValidationResult(FormatErrorMessage(null));             }         }          return ValidationResult.Success;     }      private Delegate CreateExpression(Type objectType, string expression)     {         LambdaExpression lambdaExpression = System.Linq.Dynamic.DynamicExpression.ParseLambda(objectType, typeof(bool), expression); //Added         Delegate function = lambdaExpression.Compile();         return function;     }      public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)     {         var modelClientValidationRule = new ModelClientValidationRule         {             ValidationType = "requiredif",             ErrorMessage = ErrorMessage //Added         };          modelClientValidationRule.ValidationParameters.Add("param", this.propertyName); //Added         return new List<ModelClientValidationRule> { modelClientValidationRule };     } } 

Then i applied this attribute in a property of a class like this

[RequiredIf("InAppPurchase == true", "InAppPurchase", ErrorMessage = "Please enter an in app purchase promotional price")] //Added "InAppPurchase" public string InAppPurchasePromotionalPrice { get; set; }  public bool InAppPurchase { get; set; } 

So what i want to do is display an error message that field InAppPurchasePromotionalPrice is required when InAppPurchase field is true (that means checked in the form). The following is the relevant code form the view:

<div class="control-group">                 <label class="control-label" for="InAppPurchase">Does your app include In App Purchase?</label>                 <div class="controls">                     @Html.CheckBoxFor(o => o.InAppPurchase)                     @Html.LabelFor(o => o.InAppPurchase, "Yes")                 </div>             </div>             <div class="control-group" id="InAppPurchasePromotionalPriceDiv" @(Model.InAppPurchase == true ? Html.Raw("style='display: block;'") : Html.Raw("style='display: none;'"))>                 <label class="control-label" for="InAppPurchasePromotionalPrice">App Friday Promotional Price for In App Purchase: </label>                 <div class="controls">                     @Html.TextBoxFor(o => o.InAppPurchasePromotionalPrice, new { title = "This should be at the lowest price tier of free or $.99, just for your App Friday date." })                     <span class="help-inline">                         @Html.ValidationMessageFor(o => o.InAppPurchasePromotionalPrice)                     </span>                 </div>             </div> 

This code works perfectly but when i submit the form a full post is requested on the server in order to display the message. So i created JavaScript code to enable client-side validation:

requiredif.js

(function ($) {     $.validator.addMethod('requiredif', function (value, element, params) {         /*var inAppPurchase = $('#InAppPurchase').is(':checked');          if (inAppPurchase) {             return true;         }          return false;*/          var isChecked = $(param).is(':checked');          if (isChecked) {             return false;         }          return true;     }, '');      $.validator.unobtrusive.adapters.add('requiredif', ['param'], function (options) {         options.rules["requiredif"] = '#' + options.params.param;         options.messages['requiredif'] = options.message;     }); })(jQuery); 

This is the proposed way in msdn and tutorials i have found

Of course i have also inserted the needed scripts in the form:

  1. jquery.unobtrusive-ajax.min.js
  2. jquery.validate.min.js
  3. jquery.validate.unobtrusive.min.js
  4. requiredif.js

BUT...client side validation still does not work. So could you please help me find what am i missing? Thanks in advance.

like image 921
Giorgos Manoltzas Avatar asked Nov 01 '13 12:11

Giorgos Manoltzas


People also ask

How can use client side validation in ASP.NET MVC?

Firstly, you just need to create an ASP.NET MVC application. To create a new ASP.NET MVC application, Open Visual Studio choose File, New, then Project. It will open a New Project window, from where you need to choose node Visual C# and then Web and from the right pane you need to choose ASP.NET Web Application.

Which interface is used for custom ASP .NET core client side validation?

Implementing IClientModelValidator interface This method sets certain client side custom data attributes or data-* attributes that are used by the validation system.

Which attribute is used for validation in MVC?

ASP.NET MVC provides a unique feature in which we can validate the models using the Data Annotation attribute.


1 Answers

Take a look at this: http://thewayofcode.wordpress.com/tag/custom-unobtrusive-validation/

Using this tutorial I got my custom validation code running with no problem. The only difference I can spot in your code is the way you created the $.validator.unobtrusive.adapters.add function. The parameters are a little bit different but, maybe, the problem is just that you have not defined the rule part of your adapter.

Try using something like this:

$.validator.unobtrusive.adapters.add("requiredif", ["requiredif"], function (options) {     options.rules["requiredif"] = "#" + options.params.requiredif;     options.messages["requiredif"] = options.message; }); 

or this

$.validator.unobtrusive.adapters.add("requiredif", function (options) {     options.rules["requiredif"] = "#" + options.element.name.replace('.', '_'); // mvc html helpers     options.messages["requiredif"] = options.message; }); 

About the rule (taken from the link):

The jQuery rules array for this HTML element. The adapter is expected to add item(s) to this rules array for the specific jQuery Validate validators that it wants to attach. The name is the name of the jQuery Validate rule, and the value is the parameter values for the jQuery Validate rule.

like image 188
Felipe Miosso Avatar answered Oct 07 '22 04:10

Felipe Miosso