Thuộc tính MaxLength không tạo thuộc tính xác thực phía máy khách


83

Tôi gặp sự cố tò mò với xác thực phía máy khách ASP.NET MVC3. Tôi có lớp sau:

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

Theo quan điểm của tôi:

<div class="editor-field">
    @Html.EditorFor(model => model.Name)
    @Html.ValidationMessageFor(model => model.Name)
</div>

Và đây là HTML được tạo mà tôi nhận được cho hộp văn bản cho trường này:

<input class="text-box single-line" data-val="true" data-val-required="Name is required." id="Name" name="Name" type="text" value="">

Không có dấu hiệu của MaxLengthAttribute, nhưng mọi thứ khác dường như đang hoạt động.

Bất kỳ ý tưởng có gì sai?

Câu trả lời:


151

Hãy thử sử dụng [StringLength]thuộc tính:

[Required(ErrorMessage = "Name is required.")]
[StringLength(40, ErrorMessage = "Name cannot be longer than 40 characters.")]
public string Name { get; set; }

Đó là cho mục đích xác thực. Nếu bạn muốn đặt ví dụ: thuộc tính maxlength trên đầu vào, bạn có thể viết nhà cung cấp siêu dữ liệu chú thích dữ liệu tùy chỉnh như được hiển thị trong bài đăng này và tùy chỉnh các mẫu mặc định .


3
Cảm ơn rât nhiều. Trong trường hợp có ai đó thắc mắc, tôi đã kiểm tra rằng EF Code First tạo cột DB với độ dài tối đa được áp đặt bởi thuộc tính StringLength. :)
Matt Jenkins vào

Nhưng đây không phải là câu trả lời. Bởi vì MINLENGTH thuộc tính quá không hoạt động
Hryhorii

@Greg, thuộc tính StringLength có thể chỉ định độ dài tối đa và tối thiểu.
Caleb Vear

Điều gì xảy ra nếu bạn không muốn chỉ định độ dài tối đa, chỉ là tối thiểu? Bạn đã đề xuất một cách giải quyết chủ yếu là chức năng, nhưng nó không giải quyết được vấn đề rằng thuộc tính xác thực không xác thực đúng cách.
Jeremy Holovacs

6
@JeremyHolovacs, nếu bạn không muốn chỉ định giá trị tối đa, bạn chỉ cần chỉ định int.MaxValuelà độ dài tối đa và sau đó đặt thuộc tính MinLength thành bất kỳ độ dài tối thiểu nào bạn cần. Vì vậy, không, nó không chỉ là một giải pháp chức năng. Nó cũng hoạt động trong thực tế.
Darin Dimitrov

36

Tôi vừa sử dụng một đoạn mã jquery để giải quyết vấn đề này.

$("input[data-val-length-max]").each(function (index, element) {
   var length = parseInt($(this).attr("data-val-length-max"));
   $(this).prop("maxlength", length);
});

Bộ chọn tìm tất cả các phần tử có tập thuộc tính data-val-length-max. Đây là thuộc tính mà thuộc tính xác thực StringLength sẽ đặt.

Mỗi vòng lặp lặp lại các kết quả phù hợp này và sẽ phân tích cú pháp giá trị cho thuộc tính này và gán nó cho thuộc tính mxlength lẽ ra phải được đặt.

Chỉ cần thêm điều này vào chức năng sẵn sàng tài liệu của bạn và bạn đã sẵn sàng.


Cái này khá trơn.
TheOptimusPrimus

4
bạn có thể sử dụng .data ( "val-length-max") thay vì .attr ( "data-val-length-max") :)
hatsrumandcode


8

Trong MVC 4 Nếu bạn muốn maxlenght trong văn bản kiểu đầu vào? Bạn có thể !

@Html.TextBoxFor(model => model.Item3.ADR_ZIP, new { @class = "gui-input ui-oblig", @maxlength = "5" })

4

Đạo cụ cho @ Nick-Harrison cho câu trả lời của anh ấy:

$("input[data-val-length-max]").each(function (index, element) {
var length = parseInt($(this).attr("data-val-length-max"));
$(this).prop("maxlength", length);
});

Tôi đã tự hỏi parseInt () là gì ở đó? Tôi đã đơn giản hóa nó thành điều này mà không có vấn đề gì ...

$("input[data-val-length-max]").each(function (index, element) {
    element.setAttribute("maxlength", element.getAttribute("data-val-length-max"))
});

Tôi đã nhận xét về câu trả lời của Nicks nhưng chưa có đủ đại diện.


3

Tôi gặp vấn đề tương tự và tôi đã có thể giải quyết nó bằng cách triển khai giao diện IValidatableObject trong mô hình xem của mình.

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

Đánh dấu trong Razor sau đó là ...

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

Điều này thực sự hoạt động tốt. Nếu tôi cố gắng sử dụng [StringLength] thay vào đó thì HTML được hiển thị không đúng. Việc xác nhận sẽ hiển thị như sau:

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

Với StringLengthAttribute, HTML hiển thị dưới dạng ValidationSummary không đúng. Điều buồn cười là khi trình xác nhận không thành công, việc gửi vẫn bị chặn!


2

StringLength hoạt động tuyệt vời, tôi đã sử dụng nó theo cách này:

[StringLength(25,MinimumLength=1,ErrorMessage="Sorry only 25 characters allowed for 
              ProductName")]
public string ProductName { get; set; }

hoặc Chỉ sử dụng RegularExpressionmà không có StringLength:

[RegularExpression(@"^[a-zA-Z0-9'@&#.\s]{1,25}$", ErrorMessage = "Reg Says Sorry only 25 
                   characters allowed for ProductName")]    
public string ProductName { get; set; }

nhưng đối với tôi các phương pháp trên đã gây ra lỗi trong chế độ xem hiển thị, vì tôi đã có trường Tên sản phẩm trong cơ sở dữ liệu có hơn 25 ký tự

nên cuối cùng tôi đã xem qua nàyđây bưu chính đã cố gắng để validate mà không cần mô hình như thế này :

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

điều này đã giải quyết được vấn đề của tôi, bạn cũng có thể xác thực theo cách thủ công bằng jquery hoặc sử dụng ModelState.AddModelError

hy vọng sẽ giúp ai đó.


2

Tôi biết tôi đến rất muộn với bữa tiệc, nhưng tôi đã tìm ra cách chúng tôi có thể đăng ký MaxLengthAttribute .

Trước tiên, chúng tôi cần một trình xác thực:

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

Không có gì thực sự đặc biệt. Trong hàm tạo, chúng tôi lưu một số giá trị từ thuộc tính. Trong GetClientValidationRuleschúng tôi đặt ra một quy tắc. ValidationType = "length"được ánh xạ tới data-val-lengthbởi khung. rule.ValidationParameters["max"]là cho data-val-length-maxthuộc tính.

Bây giờ vì bạn có trình xác thực, bạn chỉ cần đăng ký nó trong global.asax:

protected void Application_Start()
{
    //...

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

Et thì đấy, nó chỉ hoạt động.


1

Tôi đã thử điều này cho tất cả các đầu vào trong tài liệu html của mình (textarea, đầu vào, v.v.) có thuộc tính data-val-length-max và nó hoạt động chính xác.

$(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

Điều này có thể thay thế MaxLength và 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
Vui lòng thêm mô tả
King Stone
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.