2
votes

I need help figuring out how to succeed in implementing unobtrusive client-side validation of a field in my ASP.NET MVC 3 app. I can see that unobtrusive client-side validation is basically enabled, since MVC generates related HTML.

What I want to achieve in this case is to have validation of input to the Bugs editor (i.e., the corresponding <input> element) as I type, for testing purposes I've set the property's max length to 2. When I test, I can tell that validation does not currently take place, so something is at least missing. So, the success criteria for this question is working client-side validation of the Bugs form field.

I can see one possible problem in the generated HTML: The Verbose property is not marked as Required in the model, but its corresponding <input> still gets the dataval=true attribute for instance, whereas the <input> for Bugs does not. Shouldn't it be the other way around, as fields with validation rules should get dataval=true, to enable unobtrusive validation?

The code that should be relevant to understanding the case follows, please let me know if more info is required:

Options.cs:

public class Options
{
    [Required, StringLength(2)]
    public string Bugs;
    public bool Verbose;
}

Options.cshtml:

<script src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

<div id="options-form">
  @using (Html.BeginForm())
  {
    @Html.ValidationSummary(true)
    <fieldset>
      <legend>Options</legend>
      <div class="editor-label">
        @Html.LabelFor(model => model.Bugs)
      </div>
      <div class="editor-field">
        @Html.EditorFor(model => model.Bugs)
        @Html.ValidationMessageFor(model => model.Bugs)
      </div>
      <div class="editor-label">
        @Html.LabelFor(model => model.Verbose)
      </div>
      <div class="editor-field">
        @Html.CheckBoxFor(model => model.Verbose)
        @Html.ValidationMessageFor(model => model.Verbose)
      </div>
   </fieldset>
  }
</div>

The two editors (for Bugs and Verbose) are rendered as follows:

<div id="options-form">
<form action="/Options" method="post">
  <fieldset>
    <legend>Options</legend>
      <div class="editor-label">
        <label for="Bugs">Bugs</label>
      </div>
      <div class="editor-field">
        <input class="text-box single-line" id="Bugs" name="Bugs" type="text" value="" />
        <span class="field-validation-valid" data-valmsg-for="Bugs" data-valmsg-replace="true"></span>
      </div>
      <div class="editor-label">
        <label for="Verbose">Verbose</label>
      </div>
      <div class="editor-field">
        <input data-val="true" data-val-required="The Boolean field is required." id="Verbose" name="Verbose" type="checkbox" value="true" /><input name="Verbose" type="hidden" value="false" />
        <span class="field-validation-valid" data-valmsg-for="Verbose" data-valmsg-replace="true"></span>
      </div>
    </fieldset>
  </form>
</div>
3
Bugs and Verbose are public fields in this code, not properties. I'm not sure that has anything to do with it though.Nick Larsen
@NickLarsen Hah, that's all it took! Please submit it as an answer :)aknuds1

3 Answers

4
votes

Bugs and Verbose are public fields in this code, not properties. Make them properties and that should fix it.

2
votes

Define get; and set; for both Bugs and Verbose properties. That will not just correct(add) validation, but in the future, model binder will be able to bind models back from form fields on server.

And regarding required attribute for Verbose. That is because of implicit required validation for value types taking place. string is nullable, so it is not required if you do not set Required attribute on it explicitely - so Bugs stays without required. But bool cannot be null by nature of c#, so mvc automatically adds Required attribute to it. You can control that with

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
0
votes

I experienced the same problem recently (unobtrusive client-side validation didn't work in IE but worked in the other browsers though). The reason was in jQuery version. I rolled back from jQuery 1.6.x version to the version 1.5.2 an it started to work.