MVC data annotations range validation not working properly
Asked Answered
M

2

19

I have a RangeValidator on a property in my model to only allow Integers that are between 0 and 100. I have a partial view that displays a form to update the property via a jQuery UI dialog. I have looked at the source and can confirm that the data annotation attributes are being generated properly. However, the validatation isn't working properly. It does perform some kind of validation, but it isn't using the range I'm setting. The values 1, 10, and 100 do not produce the error. Any other single or two digit value produces the error. However, if I pad with zeros, all values less than one hundred are fine.

Model:

public class MyModel
{
  ...
  [Required(ErrorMessage = "{0} is required")]
  [Range(typeof(int), "0", "100", 
         ErrorMessage = "{0} can only be between {1} and {2}")]
  public int Percentage { get; set; }
  ...
}

Partial View:

@model MyApp.Models.Partials.MyModel

<div id="myDialog" class="editModal" title="Update Percentage">
  @using (Ajax.BeginForm("UpdatePercentage", "MyController", 
                         new AjaxOptions() { HttpMethod = "Post", 
                                             OnSuccess = "onUpdateSuccess" }, 
                         new { name = "myForm" }))
  {
    @Html.ValidationSummary(null, new { style = "width:auto;max-width:22em;               
                                                 float:left;clear:both;" })    
    <div style="width:auto;float:left;clear:both;">
      <div style="width:10em;float: left;text-align:right;clear:left;">
        @Html.Label("Percentage:")
      </div>
      <div style="width:12em;margin-left:1em;float:left;clear:right;">
        @Html.TextBoxFor(m => m.Percentage)
      </div>
    </div>
    <div style="width:23em;clear:both;text-align:center;">
      <hr />
      <input type="button" value="Cancel" class="cancelModalButton" 
             data-modal="myDialog" />
      <input type="submit" value="Submit" class="submitModalButton" 
             data-modal="myDialog" data-form="myForm" />
    </div>
  }
</div>

Markup produced:

<div id="myDialog" class="editModal" title="Update Percentage">
  <form action="/Web/MyController/UpdatePercentage?Length=3" 
        data-ajax="true" data-ajax-method="Post" data-ajax-success="onUpdateSuccess" 
        id="form2" method="post" name="myForm">
    <div class="validation-summary-valid" data-valmsg-summary="true" 
         style="width:auto;max-width:22em;float:left;clear:both;">
      <ul>
        <li style="display:none"></li>
     </ul>
    </div>
    <div style="width:auto;float:left;clear:both;margin-bottom:.75em;">
      <div style="width:10em;float: left;text-align:right;clear:left;">
        <label for="Percentage:">Percentage:</label>
      </div>
      <div style="width:12em;margin-left:1em;float:left;clear:right;">
        <input data-val="true" data-val-number="The field Percentage must be a number." 
               data-val-range="Percentage can only be between 0 and 100" 
               data-val-range-max="100" data-val-range-min="0" 
               data-val-required="Percentage is required" id="Percentage" 
               name="Percentage" type="text" value="10" />
      </div>
    </div>
    <div style="width:23em;clear:both;text-align:center;">
      <hr />
      <input type="button" value="Cancel" class="cancelModalButton" data-modal="myDialog" />
      <input type="submit" value="Submit" class="submitModalButton" data-modal="myDialog" data-form="myForm" />
    </div>
  </form>
</div>

I see that the type is set to text, and if I change my TextBoxFor to EditorFor it chnages to number but I still see the same behavior.

Martyrdom answered 12/3, 2013 at 19:49 Comment(1)
it is an issue with breaking changes to jquery, see: #14889931Excommunicate
M
7

I had this exact problem and found the solution here. You need to upgrade the following:

jQuery Validation (at least 1.11.1)
Microsoft jQuery Unobtrusive Validation (at least 2.0.30116.0)
Microsoft jQuery Unobtrusive Ajax (at least 2.0.30116.0)

The problem was introduced by breaking changes in jQuery 1.9.1

Malorie answered 17/7, 2013 at 16:40 Comment(2)
This did end up being the problem, as felickz pointed out as a comment a while back, but since you're the first to propose it as an official answer I'll give you the credit to mark it as resolved.Martyrdom
Thanks. I started here and followed felickz's link...then followed a link from there to the issue on GitHub...then scrolled down to a comment that said jQuery Validation 1.11.1 fixed it....so I thought I would make it a little easier for any that followMalorie
S
3

Try [Range(0, 100)]. Remove ErrorMessage completely to see that you not breaking anything with wrong formatting and curly brackets.

If pure range doesn't work properly let force (MS) be with you! :)

Soane answered 13/3, 2013 at 3:46 Comment(4)
Done. Same error. Removed all other properties from the Model, removed the Required annotation, changed the Range to exactly what you have here. I even took the form and moved it out of the Partial view and made it no longer a dialog. Same error. Then I took data annotations out of the equation. I took the markup for the input that was being generated and plugged that directly into the page instead of generating it from my model. Same error.Martyrdom
At this moment in time, you need the force to be with you :) I'd start commenting out portions of your code to isolate the problem. Because Range works all the way, there's no problem with it, I think it might be some conflict or versions mismatch, but I don't expect people on the forum will debug this thing for you remotely. Just isolate the problem. Other way to act (if you don't yet have too much code) will be to just create new solution and move your code over there by pieces checking every time you bring something new that Range is still working. Hope this helps.Soane
I really appreciate your help, but I decided just to punt and use a RegularExpression validator instead, which is just as viable in my situation. I've spent too much time on it. I guess MS wins this round...Martyrdom
Absolutely. My next advise would be exactly that - RegEx is faster probably than finding the problem in the hay. Thing is - Range is working, was working and supposedly will - never seen the situation when [Range(x, y)] wouldn't work. It just doesn't make sense. One last thing - try looking into here #15300218. The guy have Range not working because of Java Script library called "modernizr". Strange but true, Read it in the comments to my response.Soane

© 2022 - 2024 — McMap. All rights reserved.