Mam ciekawy problem z walidacją po stronie klienta ASP.NET MVC3. Mam następującą klasę:
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; }
}
Z mojego punktu widzenia:
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
A oto wygenerowany kod HTML, który otrzymałem dla pola tekstowego dla tego pola:
<input class="text-box single-line" data-val="true" data-val-required="Name is required." id="Name" name="Name" type="text" value="">
Brak śladu MaxLengthAttribute
, ale wszystko inne wydaje się działać.
Jakieś pomysły, co się dzieje?
c#
asp.net-mvc
validation
asp.net-mvc-3
model-validation
Matt Jenkins
źródło
źródło
int.MaxValue
maksymalnej długości , po prostu określ jako maksymalną długość, a następnie ustaw właściwość MinLength na dowolną minimalną długość, której potrzebujesz. Więc nie, to nie jest tylko funkcjonalne obejście. To działa również w praktyce.Właśnie użyłem fragmentu jQuery, aby rozwiązać ten problem.
$("input[data-val-length-max]").each(function (index, element) { var length = parseInt($(this).attr("data-val-length-max")); $(this).prop("maxlength", length); });
Selektor znajduje wszystkie elementy, które mają ustawiony atrybut data-val-length-max. Jest to atrybut, który zostanie ustawiony przez atrybut walidacji StringLength.
Każda pętla przechodzi przez te dopasowania i analizuje wartość tego atrybutu i przypisuje ją do właściwości mxlength, która powinna zostać ustawiona.
Po prostu dodaj to do swojej funkcji przygotowania dokumentu i gotowe.
źródło
MaxLengthAttribute
działa od aktualizacji MVC 5.1: zmiany notatekźródło
maxlength
atrybutu doinput
elementu.W MVC 4 Jeśli chcesz mieć maksymalną długość w tekście wejściowym? Możesz !
@Html.TextBoxFor(model => model.Item3.ADR_ZIP, new { @class = "gui-input ui-oblig", @maxlength = "5" })
źródło
Podziękowania dla @ Nicka-Harrisona za jego odpowiedź:
$("input[data-val-length-max]").each(function (index, element) { var length = parseInt($(this).attr("data-val-length-max")); $(this).prop("maxlength", length); });
Zastanawiałem się, do czego służy parseInt ()? Uprościłem to do tego bez żadnych problemów ...
$("input[data-val-length-max]").each(function (index, element) { element.setAttribute("maxlength", element.getAttribute("data-val-length-max")) });
Skomentowałbym odpowiedź Nicka, ale nie mam jeszcze wystarczającej liczby powtórzeń.
źródło
Miałem ten sam problem i udało mi się go rozwiązać, implementując interfejs IValidatableObject w moim modelu widoku.
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; } }
Znacznik w Razor jest więc ...
<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>
To działa naprawdę dobrze. Jeśli zamiast tego spróbuję użyć [StringLength], renderowany kod HTML jest po prostu nieprawidłowy. Walidacja powinna wyglądać następująco:
<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>
W przypadku StringLengthAttribute renderowany kod HTML jest wyświetlany jako podsumowanie walidacji, które nie jest poprawne. Zabawne jest to, że jeśli walidator się nie powiedzie, przesyłanie jest nadal blokowane!
źródło
StringLength
działa świetnie, użyłem go w ten sposób:[StringLength(25,MinimumLength=1,ErrorMessage="Sorry only 25 characters allowed for ProductName")] public string ProductName { get; set; }
lub po prostu użyj
RegularExpression
bez StringLength:[RegularExpression(@"^[a-zA-Z0-9'@&#.\s]{1,25}$", ErrorMessage = "Reg Says Sorry only 25 characters allowed for ProductName")] public string ProductName { get; set; }
ale dla mnie powyższe metody dały błąd w widoku wyświetlacza, ponieważ miałem już pole ProductName w bazie danych, które miało więcej niż 25 znaków
więc w końcu natknąłem się na ten i ten post i próbowałem zweryfikować bez modelu w ten sposób :
<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>
rozwiązało to mój problem, możesz również przeprowadzić walidację ręcznie za pomocą jquery lub za pomocą ModelState.AddModelError
nadzieja pomaga komuś.
źródło
Wiem, że jestem bardzo spóźniony na przyjęcie, ale w końcu dowiedziałem się, jak możemy zarejestrować
MaxLengthAttribute
.Najpierw potrzebujemy walidatora:
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; } }
Nic specjalnego. W konstruktorze zapisujemy pewne wartości z atrybutu. W
GetClientValidationRules
mamy ustaloną regułę.ValidationType = "length"
jest odwzorowywanydata-val-length
przez framework.rule.ValidationParameters["max"]
dotyczydata-val-length-max
atrybutu.Teraz, skoro masz walidator, musisz go zarejestrować tylko w
global.asax
:protected void Application_Start() { //... //Register Validator DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MaxLengthAttribute), typeof(MaxLengthClientValidator)); }
Et voila, po prostu działa.
źródło
Próbowałem tego dla wszystkich danych wejściowych w moim dokumencie html (obszar tekstowy, dane wejściowe itp.), Które miały właściwość data-val-length-max i działa poprawnie.
$(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); }); });
źródło
Może to zastąpić MaxLength i MinLength
[StringLength(40, MinimumLength = 10 , ErrorMessage = "Name cannot be longer than 40 characters and less than 10")]
źródło
<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; });
źródło