Атрибут 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
, но все остальное, кажется, работает.
есть идеи, что происходит не так?
10 ответов:
попробуйте использовать :
[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-val-length-max. Это атрибут, который будет установлен атрибут проверки StringLength.
каждый цикл проходит через эти совпадения и будет анализировать значение для этого атрибута и присваивать его свойству mxlength, которое должно было быть установлено.
просто добавьте эту функцию к вам документ готов и вы мы готовы идти.
MaxLengthAttribute
работает с момента обновления MVC 5.1:изменить Примечания
в MVC 4 Если вы хотите maxlenght в типе ввода текста ? Ты можешь !
@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; } }
разметка в бритве тогда...
<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, что неверно. Шутка дело в том, что когда валидатор не отправить по-прежнему заблокирован!
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
надеюсь кому-нибудь поможет.
Я знаю, что я очень поздно на вечеринку, но я наконец узнал, как мы можем зарегистрировать
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"]
на .теперь, поскольку у вас есть валидатор, вам нужно только зарегистрировать его
global.asax
:protected void Application_Start() { //... //Register Validator DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MaxLengthAttribute), typeof(MaxLengthClientValidator)); }
и вуаля, все работает.
я попробовал это для всех входных данных в моем 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); }); });