6

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

Steven
  • 16,943
  • 64
  • 174
  • 272

3 Answers3

11

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

Community
  • 1
  • 1
MorioBoncz
  • 860
  • 11
  • 21
4

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

Muhammad Adeel Zahid
  • 16,658
  • 13
  • 86
  • 147
0

A Remote Validator is what you need here is the link http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-1

Hamdi Baligh
  • 826
  • 1
  • 11
  • 29