【问题标题】:MaxLength Attribute not generating client-side validation attributesMaxLength 属性不生成客户端验证属性
【发布时间】:2011-10-11 17:07:33
【问题描述】:

我对 ASP.NET MVC3 客户端验证有一个奇怪的问题。我有以下课程:

public class Instrument : BaseObject
{
    public int Id { get; set; }

    [Required(ErrorMessage = "Name is required.")]
    [MaxLength(40, ErrorMessage = "Name cannot be longer than 40 characters.")]
    public string Name { get; set; }
}

在我看来:

<div class="editor-field">
    @Html.EditorFor(model => model.Name)
    @Html.ValidationMessageFor(model => model.Name)
</div>

这是我为该字段的文本框生成的 HTML:

<input class="text-box single-line" data-val="true" data-val-required="Name is required." id="Name" name="Name" type="text" value="">

没有MaxLengthAttribute 的迹象,但其他一切似乎都在工作。

有什么想法吗?

【问题讨论】:

    标签: c# asp.net-mvc validation asp.net-mvc-3 model-validation


    【解决方案1】:
    <input class="text-box single-line" data-val="true" data-val-required="Name is required." 
        id="Name1" name="Name" type="text" value="">
    
    $('#Name1').keypress(function () {
        if (this.value.length >= 5) return false;
    });
    

    【讨论】:

    • 请添加描述
    【解决方案2】:

    我对我的 html 文档(textarea、inputs 等)中具有 data-val-length-max 属性的所有输入都进行了尝试,并且它可以正常工作。

    $(document).ready(function () {
        $(":input[data-val-length-max]").each(function (index, element) {
            var length = parseInt($(this).attr("data-val-length-max"));
            $(this).prop("maxlength", length);
        });
    });
    

    【讨论】:

      【解决方案3】:

      我知道我参加聚会很晚了,但我终于知道了如何注册MaxLengthAttribute。

      首先我们需要一个验证器:

      public class MaxLengthClientValidator : DataAnnotationsModelValidator<MaxLengthAttribute>
      {
          private readonly string _errorMessage;
          private readonly int _length;
      
      
          public MaxLengthClientValidator(ModelMetadata metadata, ControllerContext context, MaxLengthAttribute attribute)
          : base(metadata, context, attribute)
          {
              _errorMessage = attribute.FormatErrorMessage(metadata.DisplayName);
              _length = attribute.Length;
          }
      
          public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
          {
              var rule = new ModelClientValidationRule
              {
                  ErrorMessage = _errorMessage,
                  ValidationType = "length"
              };
      
              rule.ValidationParameters["max"] = _length;
              yield return rule;
          }
      }
      

      没什么特别的。在构造函数中,我们从属性中保存一些值。在GetClientValidationRules 中我们设置了一个规则。 ValidationType = "length" 被框架映射到 data-val-length。 rule.ValidationParameters["max"] 用于 data-val-length-max 属性。

      现在既然你有一个验证器,你只需要在global.asax注册它:

      protected void Application_Start()
      {
          //...
      
          //Register Validator
          DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MaxLengthAttribute), typeof(MaxLengthClientValidator));
      }
      

      瞧,它只是工作。

      【讨论】:

        【解决方案4】:

        尝试使用[StringLength] 属性:

        [Required(ErrorMessage = "Name is required.")]
        [StringLength(40, ErrorMessage = "Name cannot be longer than 40 characters.")]
        public string Name { get; set; }
        

        这是出于验证目的。例如,如果您想在输入中设置 maxlength 属性,您可以将自定义数据注释元数据提供程序编写为 shown in this post 并自定义 default templates。

        【讨论】:

        • 非常感谢。如果有人想知道,我检查了 EF Code First 是否创建了具有 StringLength 属性施加的最大长度的 DB 列。 :)
        • 但这不是答案。因为 MinLength 属性也不起作用
        • @Greg,StringLength属性可以指定最大最小长度。
        • 如果您不想指定最大长度,只需指定一个最小值怎么办?您提出了一个主要功能性的解决方法,但它没有解决验证属性未正确验证的问题。
        • @JeremyHolovacs,如果您不想指定最大值,只需将 int.MaxValue 指定为最大长度,然后将 MinLength 属性设置为您需要的任何最小长度。所以,不,这不仅仅是一种功能性的解决方法。它在实践中也很有效。
        【解决方案5】:

        这可以代替 MaxLength 和 MinLength

        [StringLength(40, MinimumLength = 10 , ErrorMessage = "Name cannot be longer than 40 characters and less than 10")]
        

        【讨论】:

          【解决方案6】:

          感谢@Nick-Harrison 的回答:

          $("input[data-val-length-max]").each(function (index, element) {
          var length = parseInt($(this).attr("data-val-length-max"));
          $(this).prop("maxlength", length);
          });
          

          我想知道 parseInt() 是干什么用的?我已经将其简化为没有问题...

          $("input[data-val-length-max]").each(function (index, element) {
              element.setAttribute("maxlength", element.getAttribute("data-val-length-max"))
          });
          

          我会评论尼克斯的回答,但还没有足够的代表。

          【讨论】:

            【解决方案7】:

            在 MVC 4 中 如果您想要输入类型文本中的 maxlenght ?你可以 !

            @Html.TextBoxFor(model => model.Item3.ADR_ZIP, new { @class = "gui-input ui-oblig", @maxlength = "5" })
            

            【讨论】:

              【解决方案8】:

              我遇到了同样的问题,我可以通过在我的视图模型中实现 IValidatableObject 接口来解决它。

              public class RegisterViewModel : IValidatableObject
              {
                  /// <summary>
                  /// Error message for Minimum password
                  /// </summary>
                  public static string PasswordLengthErrorMessage => $"The password must be at least {PasswordMinimumLength} characters";
              
                  /// <summary>
                  /// Minimum acceptable password length
                  /// </summary>
                  public const int PasswordMinimumLength = 8;
              
                  /// <summary>
                  /// Gets or sets the password provided by the user.
                  /// </summary>
                  [Required]
                  [DataType(DataType.Password)]
                  [Display(Name = "Password")]
                  public string Password { get; set; }
              
                  /// <summary>
                  /// Only need to validate the minimum length
                  /// </summary>
                  /// <param name="validationContext">ValidationContext, ignored</param>
                  /// <returns>List of validation errors</returns>
                  public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
                  {
                      var errorList = new List<ValidationResult>();
                      if ((Password?.Length ?? 0 ) < PasswordMinimumLength)
                      {
                          errorList.Add(new ValidationResult(PasswordLengthErrorMessage, new List<string>() {"Password"}));
                      }
                      return errorList;
                  }
              }
              

              那么 Razor 中的标记是...

              <div class="form-group">
                  @Html.LabelFor(m => m.Password)
                  @Html.PasswordFor(m => m.Password, new { @class = "form-control input-lg" }
                  <div class="password-helper">Must contain: 8 characters, 1 upper-case, 1 lower-case
                  </div>
                  @Html.ValidationMessagesFor(m => m.Password, new { @class = "text-danger" })
              </div>
              

              这真的很好用。如果我尝试使用 [StringLength] 代替,那么呈现的 HTML 就是不正确的。验证应呈现为:

              <span class="text-danger field-validation-invalid field-validation-error" data-valmsg-for="Password" data-valmsg-replace="true"><span id="Password-error" class="">The Password should be a minimum of 8 characters long.</span></span>
              

              使用 StringLengthAttribute,呈现的 HTML 显示为不正确的 ValidationSummary。有趣的是,当验证器失败时,提交仍然被阻止!

              【讨论】:

                【解决方案9】:

                StringLength 很好用,我是这样用的:

                [StringLength(25,MinimumLength=1,ErrorMessage="Sorry only 25 characters allowed for 
                              ProductName")]
                public string ProductName { get; set; }
                

                或只使用RegularExpression而不使用StringLength:

                [RegularExpression(@"^[a-zA-Z0-9'@&#.\s]{1,25}$", ErrorMessage = "Reg Says Sorry only 25 
                                   characters allowed for ProductName")]    
                public string ProductName { get; set; }
                

                但对我来说,上述方法在显示视图中出现错误,因为我已经在数据库中拥有超过 25 个字符的 ProductName 字段

                所以最后我遇到了this 和this 的帖子,并尝试在没有这样的模型的情况下进行验证:

                 <div class="editor-field">
                 @Html.TextBoxFor(model => model.ProductName, new
                 {
                 @class = "form-control",
                 data_val = "true",
                 data_val_length = "Sorry only 25 characters allowed for ProductName",
                 data_val_length_max = "25",
                 data_val_length_min = "1"
                 })
                 <span class="validation"> @Html.ValidationMessageFor(model => model.ProductName)</span>
                 </div>
                

                这解决了我的问题,您也可以使用jquery 或ModelState.AddModelError 手动进行验证

                希望能帮助别人。

                【讨论】:

                  【解决方案10】:

                  MaxLengthAttribute 自 MVC 5.1 更新后开始工作:change notes

                  【讨论】:

                  • 它现在可以用于验证,但 MVC 仍然没有将 maxlength 属性应用于 input 元素。
                  • I wrote an framework extension,这正是@ladenedge
                  【解决方案11】:

                  我只是用了一个jquery的sn-p来解决这个问题。

                  $("input[data-val-length-max]").each(function (index, element) {
                     var length = parseInt($(this).attr("data-val-length-max"));
                     $(this).prop("maxlength", length);
                  });
                  

                  选择器查找所有设置了 data-val-length-max 属性的元素。这是 StringLength 验证属性将设置的属性。

                  each 循环遍历这些匹配项,并将解析出该属性的值并将其分配给应设置的 mxlength 属性。

                  只需将此添加到您的文档就绪功能,您就可以开始了。

                  【讨论】:

                  • 这很漂亮。
                  • 你可以使用 .data("val-length-max") 代替 .attr("data-val-length-max") :)
                  猜你喜欢
                  • 2011-10-03
                  • 1970-01-01
                  • 2014-06-15
                  • 2018-05-15
                  • 2014-04-04
                  • 2012-03-06
                  • 2015-05-16
                  • 1970-01-01
                  • 2020-11-15
                  相关资源
                  最近更新 更多