Атрибут MaxLength не генерирует атрибуты проверки на стороне клиента
У меня есть любопытная проблема с проверкой на стороне клиента 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
, но все остальное работает.
Любые идеи, что происходит не так?
Ответы
Ответ 1
Попробуйте использовать атрибут [StringLength]
:
[Required(ErrorMessage = "Name is required.")]
[StringLength(40, ErrorMessage = "Name cannot be longer than 40 characters.")]
public string Name { get; set; }
Это для целей проверки. Если вы хотите установить, например, атрибут maxlength на входе, вы можете написать создатель метаданных пользовательских данных аннотаций в качестве показанный в этом сообщении, и настроить шаблоны по умолчанию.
Ответ 2
Я просто использовал фрагмент 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, которое должно было быть установлено.
Просто добавьте эту функцию в документ, и вы хорошо пойдете.
Ответ 3
MaxLengthAttribute
работает с обновления MVC 5.1: изменить примечания
Ответ 4
В MVC 4
Если вы хотите, чтобы maxlenght вводил текст типа ввода? Ты можешь!
@Html.TextBoxFor(model => model.Item3.ADR_ZIP, new { @class = "gui-input ui-oblig", @maxlength = "5" })
Ответ 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"))
});
Я бы прокомментировал ответ Nicks, но пока не получил достаточного количества rep.
Ответ 6
У меня была такая же проблема, и я смог ее решить, реализовав интерфейс 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, что неверно. Самое смешное в том, что, когда валидатор терпит неудачу, подача по-прежнему блокируется!
Ответ 7
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; }
но для меня выше методы дали ошибку в представлении отображения, потому что у меня уже было поле ProductName в базе данных, в котором было более 25 символов
так что, наконец, я наткнулся на этот и этот и попытался проверять без модели:
<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
Надежда помогает кому-то.
Ответ 8
Я знаю, что я очень опаздываю на вечеринку, но я наконец узнал, как мы можем зарегистрировать 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));
}
Et voila, он просто работает.
Ответ 9
Я попробовал это для всех входов в моем html-документе (textarea, input и т.д.), у которого было свойство 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);
});
});
Ответ 10
Это может заменить MaxLength и MinLength
[StringLength(40, MinimumLength = 10 , ErrorMessage = "Name cannot be longer than 40 characters and less than 10")]
Ответ 11
<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;
});