MaxLength属性未生成客户端验证属性


83

我对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,但其他所有内容似乎都在起作用。

任何想法出什么事了吗?

Answers:


151

尝试使用[StringLength]属性:

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

这是出于验证目的。例如,如果要在输入上设置maxlength属性,则可以编写一个自定义数据注释元数据提供程序,如本文所述,并自定义默认模板


3
非常感谢你。如果有人想知道,我检查了EF Code First是否创建了StringLength属性施加最大长度的DB列。:)
马特·詹金斯

但这不是答案。由于MinLength属性也无法使用
Hryhorii 2011年

@ Greg,StringLength属性可以指定最大和最小长度。
Caleb Vear 2011年

如果您不想指定最大长度,而只是一个最小值,该怎么办?您已经提出了一个主要的功能性解决方法,但是它不能解决验证属性未正确验证的问题。
Jeremy Holovacs 2011年

6
@JeremyHolovacs,如果您不想指定最大值,则只需指定int.MaxValue为最大长度,然后将MinLength属性设置为所需的任何最小长度即可。因此,不,这不仅仅是功能性的解决方法。这也是一种在实践中也有效的方法。
达林·迪米特洛夫

36

我只是用一小段jquery来解决这个问题。

$("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验证属性将设置的属性。

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

只需将其添加到您的文档准备功能中,您就可以使用了。


这很漂亮。
TheOptimusPrimus 2013年

4
您可以使用.data(“ val-length-max”)代替.attr(“ data-val-length-max”):)
hatsrumandcode 2016年


8

在MVC 4中是否要在输入类型文本中最大化?您可以 !

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

4

@ 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"))
});

我会对尼克斯的答案发表评论,但没有足够的代表。


3

我遇到了同样的问题,并且可以通过在视图模型中实现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;
    }
}

剃刀中的标记是...

<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,这是不正确的。有趣的是,当验证器失败时,提交仍被阻止!


2

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字段

所以最后我碰到了这个这个帖子,并试图在没有这样的模型的情况下进行验证

 <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手动进行验证

希望可以帮助某人。


2

我知道我参加聚会很晚,但是我最终确定了我们该如何注册 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-lengthrule.ValidationParameters["max"]用于data-val-length-max属性。

现在,有了验证器,您只需在global.asax以下位置进行注册:

protected void Application_Start()
{
    //...

    //Register Validator
    DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MaxLengthAttribute), typeof(MaxLengthClientValidator));
}

等等,它就是有效的。


1

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

$(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);
    });
});

0

这可以代替MaxLength和MinLength

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

0
<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;
});

6
请添加描述
金山
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.