Client-side custom data annotation validation

11,345

Solution 1

Had same issue recently. You can write:

$.validator.addMethod('enforcetrue', function (value, element) {
    return $(element).is(":checked");
});
$.validator.unobtrusive.adapters.add('enforcetrue', [], function (options) {
    options.messages['enforcetrue'] = options.message;
    options.rules['enforcetrue'] = options.params;
});

Similar question here ASP.NET MVC 3 client-side validation

Solution 2

Implementing Iclientvalidatable only adds unobtrusive attributes to generated html inputs. To enable validation on client side you must write validators that use these unobtrusive attributes to validate the inputs. Here you can find very good explanation of client and server validation in asp.net mvc 3

Share:
11,345
Steven
Author by

Steven

Updated on June 14, 2022

Comments

  • Steven
    Steven almost 2 years

    I've create a custom data annotation to do some validation on my view model. The problem is that it doesn't validate on the client-side. Here's my model:

    public class MemberViewModel
    {
        [ScaffoldColumn(false)]
        public int MemberId { get; set; }
    
        [Required(ErrorMessage = "Name is required")]
        public string Name { get; set; }
    
        //My custom data annotation
        [EnforceTrue(ErrorMessage = "You must agree to the Terms and Conditions")]
        public bool AgreeTerms { get; set; }
    }
    

    My data annotation validation code:

    public class EnforceTrueAttribute : ValidationAttribute, IClientValidatable
    {
        public EnforceTrueAttribute() { }
    
        public override bool IsValid(object value)
        {
            return value != null && (bool)value == true;
        }
    
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            yield return new ModelClientValidationRule() { ValidationType = "enforcetrue", ErrorMessage = this.ErrorMessageString };
        }
    }
    

    My controller method:

    [HttpPost]
    public ActionResult Index(MemberViewModel viewModel)
    {
        Member member = new Member();
        TryUpdateModel(member);
    
        if (ModelState.IsValid)
        {
            _membersRepository.SaveMember(member);
    
            return RedirectToAction("Index", "Home");       
        }
    
        return View(viewModel);     // validation error, so redisplay same view            
    }
    

    And my view:

    @using (Html.BeginForm("Index", "Members", FormMethod.Post)) {
    
        @Html.HiddenFor(m => m.MemberId)
    
        <div class="editor-label">@Html.LabelFor(model => model.Name)</div>
        <div class="editor-field">@Html.TextBoxFor(model => model.Name)</div>
    
        <div class="editor-field">@Html.CheckBoxFor(model => model.AgreeTerms) <label for="AgreeTerms">I agree to the Terms and Conditions</label></div>
    
        <p>
            <input type="submit" value="Submit" />
        </p>
    
        @Html.ValidationSummary()
    }
    

    So all my other error messages get displayed in the validation summary with client-side validation. But for my custom data annotation, the error message doesn't show until the rest of the model is valid, and after you submit the form and page reloads, that's when the error is displayed in the summary.

    Is there something else I need to do here to get it to show up in the summary with the other errors?

    I'm using C# and ASP.NET MVC 3