MaxLength属性不生成客户端验证属性
本文关键字:属性 客户端 验证 MaxLength | 更新日期: 2023-09-27 18:03:32
我对ASP有一个奇怪的问题。NET mvc客户端验证。我有以下类:
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; }
}
From my view:
<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
的迹象,但其他一切似乎都在工作。
你知道出了什么问题吗?
尝试使用[StringLength]
属性:
[Required(ErrorMessage = "Name is required.")]
[StringLength(40, ErrorMessage = "Name cannot be longer than 40 characters.")]
public string Name { get; set; }
这是为了验证目的。例如,如果你想设置输入的maxlength属性,你可以编写一个自定义数据注释元数据提供程序,如本文所示,并自定义默认模板。
我只是使用了一小段jquery来解决这个问题。
$("input[data-val-length-max]").each(function (index, element) {
var length = parseInt($(this).attr("data-val-length-max"));
$(this).prop("maxlength", length);
});
选择器查找具有data- value -length-max属性集的所有元素。这是StringLength验证属性将设置的属性。
each循环遍历这些匹配项,并将解析出该属性的值,并将其分配给应该设置的mxlength属性。
只要把这个添加到你的文档准备函数,你就可以开始了
MaxLengthAttribute
是工作自从MVC 5.1更新:更改说明
@Html.TextBoxFor(model => model.Item3.ADR_ZIP, new { @class = "gui-input ui-oblig", @maxlength = "5" })
感谢@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"))
});
我本想评论尼克斯的回答,但现在还没有足够的代表。
我有同样的问题,我能够通过在我的视图模型中实现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,这是不正确的。有趣的是,当验证器失败时,提交仍然被阻止!
我知道我来晚了,但我终于找到了注册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));
}
好了,它就成功了
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
希望能帮助别人。
我尝试了所有的输入在我的html文档(textarea,input等),有data- value -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);
});
});
可以代替MaxLength和MinLength
[StringLength(40, MinimumLength = 10 , ErrorMessage = "Name cannot be longer than 40 characters and less than 10")]
<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;
});