web-dev-qa-db-ger.com

MaxLength-Attribut generiert keine clientseitigen Validierungsattribute

Ich habe ein seltsames Problem mit der clientseitigen Validierung von ASP.NET MVC3. Ich habe folgende Klasse:

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

Aus meiner Sicht:

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

Und hier ist der generierte HTML-Code für das Textfeld für dieses Feld:

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

Kein Zeichen der MaxLengthAttribute, aber alles andere scheint zu funktionieren.

Irgendwelche Ideen, was schief läuft?

72
Matt Jenkins

Versuchen Sie es mit dem [StringLength]-Attribut:

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

Das ist zu Validierungszwecken. Wenn Sie beispielsweise das Maxlength-Attribut für die Eingabe festlegen möchten, können Sie einen Metadatenprovider für benutzerdefinierte Annotationsdaten schreiben, wie in diesem Beitrag gezeigt und die Standardvorlagen anpassen.

136
Darin Dimitrov

Ich habe nur ein Jquery-Snippet verwendet, um dieses Problem zu lösen.

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

Der Selektor findet alle Elemente, die ein Attribut data-val-length-max enthalten. Dies ist das Attribut, das das StringLength-Validierungsattribut setzt.

Jede Schleife durchläuft diese Übereinstimmungen und durchläuft den Wert für dieses Attribut und ordnet es der Eigenschaft mxlength zu, die festgelegt werden sollte.

Fügen Sie dies einfach zu Ihrer dokumentenfertigen Funktion hinzu und Sie können loslegen.

35
Nick Harrison

MaxLengthAttribute arbeitet seit dem Update von MVC 5.1: Änderungshinweise

8
Michael Logutov

In MVC 4 Wenn Sie maxlength in text eingeben möchten? Sie können ! 

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

Requisiten an @ Nick-Harrison für seine Antwort:

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

Ich habe mich gefragt, was der parseInt () für da ist? Ich habe es dazu ohne Probleme vereinfacht ...

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

Ich hätte Nicks Antwort kommentiert, habe aber noch nicht genug Vertreter.

4
EamonnM

Ich hatte das gleiche Problem und konnte es lösen, indem ich die IValidatableObject-Schnittstelle in meinem Ansichtsmodell implementierte. 

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

Das Markup im Rasiermesser ist dann ...

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

Das funktioniert wirklich gut. Wenn ich versuche, stattdessen [StringLength] zu verwenden, ist das gerenderte HTML einfach nicht korrekt. Die Validierung sollte folgendermaßen lauten:

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

Mit dem StringLengthAttribute wird der gerenderte HTML-Code als nicht gültige ValidationSummary angezeigt. Die lustige Sache ist, dass, wenn der Validator fehlschlägt, das Senden immer noch blockiert ist! 

3
ScottyMacDev

StringLength funktioniert super, ich habe es so benutzt:

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

oder Verwenden Sie einfach RegularExpression ohne StringLength:

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

bei mir oben genannten Methoden gab es jedoch Fehler in der Anzeigeansicht, da ich bereits ein ProductName-Feld in der Datenbank hatte, das mehr als 25 Zeichen hatte

so endlich habe ich this und this post gefunden und versucht, ohne Modell wie folgt zu validieren:

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

nachdem dieses Problem gelöst wurde, können Sie die Validierung auch manuell mit jquery oder mit ModelState.AddModelError durchführen.

hoffnung hilft jemandem.

2
stom

Ich habe dies für alle Eingaben in meinem HTML-Dokument (Textbereich, Eingaben usw.) versucht, die über die Eigenschaft data-val-length-max verfügten, und es funktioniert ordnungsgemäß.

$(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);
    });
});

Ich weiß, dass ich sehr spät zur Party bin, aber ich habe endlich herausgefunden, wie wir die MaxLengthAttribute registrieren können.

Zuerst brauchen wir einen Validator:

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

Nichts wirklich Besonderes. Im Konstruktor speichern wir einige Werte aus dem Attribut. In GetClientValidationRules setzen wir eine Regel. ValidationType = "length" wird vom Framework auf data-val-length abgebildet. rule.ValidationParameters["max"] ist für das data-val-length-max-Attribut.

Jetzt, da Sie einen Validator haben, müssen Sie ihn nur noch in global.asax registrieren:

protected void Application_Start()
{
    //...

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

Et voila, es funktioniert einfach.

1

Dies kann die MaxLength und die MinLength ersetzen

[StringLength(40, MinimumLength = 10 , ErrorMessage = "Name cannot be longer than 40 characters and less than 10")]
0
amal50
<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;
});
0
Nithya