클라이언트 측 유효성 검사 속성을 생성하지 않는 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없지만 다른 모든 것이 작동하는 것 같습니다.

무슨 일이 일어나고 있는지 아이디어가 있습니까?

답변:


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 열을 생성하는지 확인했습니다. :)
Matt Jenkins

그러나 이것은 답이 아닙니다. MINLENGTH 속성도 작동하지 않을 수 있기 때문에
흐리 호리

@Greg, StringLength 속성은 최대 및 최소 길이를 지정할 수 있습니다.
Caleb Vear 2011 년

최대 길이를 지정하지 않고 최소값 만 지정하고 싶다면 어떻게해야합니까? 대부분 기능적인 해결 방법을 제안했지만 유효성 검사 속성이 제대로 확인되지 않는 문제는 해결하지 못합니다.
Jeremy Holovacs 2011 년

7
@JeremyHolovacs, 최대 값을 지정하지 않으려면 int.MaxValue최대 길이로 지정한 다음 MinLength 속성을 필요한 최소 길이로 설정하면됩니다. 따라서 아니요, 단순한 기능적 해결 방법이 아닙니다. 실제로도 작동하는 것입니다.
Darin Dimitrov 2011 년

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-08-07

4
당신은 ( "데이터 발 길이 - 최대") .attr 대신 ( "발 길이 - 최대") : .DATA 사용할 수 있습니다
hatsrumandcode


8

MVC 4에서 입력 유형 텍스트에서 maxlenght를 원하십니까? 당신은 할 수 있습니다!

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

나는 Nicks 대답에 대해 언급했지만 아직 충분한 담당자가 없습니다.


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

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로 표시됩니다. 재미있는 점은 유효성 검사기가 실패해도 제출이 여전히 차단된다는 것입니다!


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-length의해 매핑됩니다 . rule.ValidationParameters["max"]입니다 data-val-length-max속성.

이제 유효성 검사기가 있으므로 다음 위치에서만 등록하면됩니다 global.asax.

protected void Application_Start()
{
    //...

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

Et voila, 그냥 작동합니다.


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
설명을 추가하십시오
King Stone 19
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.