Domanda

Ho un problema curioso con ASP.NET MVC3 convalida lato client. Ho la seguente classe:

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

Dal mio punto di vista:

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

Ed ecco l'HTML generato ottengo per la casella di testo per questo campo:

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

Nessun segno del MaxLengthAttribute, ma tutto il resto sembra funzionare.

Tutte le idee che sta andando male?

È stato utile?

Soluzione

Prova a usare l'attributo [StringLength]:

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

Questo è per la convalida. Se si desidera impostare, ad esempio l'attributo maxlength sull'ingresso si potrebbe scrivere un annotazioni di dati personalizzati fornitore di metadati come indicati in questo post e personalizzare il modelli predefiniti .

Altri suggerimenti

Ho appena utilizzato un frammento di jQuery per risolvere questo problema.

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

Il selettore trova tutti gli elementi che hanno una serie attributo data-val-lunghezza max. Questo è l'attributo che l'attributo di convalida StringLength imposterà.

I loop ogni ciclo attraverso queste partite e analizzerà il valore di questo attributo e assegnare alla proprietà mxlength che avrebbe dovuto essere impostato.

Basta aggiungere questo a voi documentare la funzione pronti e siete a posto.

MaxLengthAttribute sta lavorando dal MVC 5.1 update: cambiamento note

In MVC 4 Se si desidera maxlength nel testo tipo di ingresso? Puoi !

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

Props a @ Nick-Harrison per la sua risposta:

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

Mi chiedevo che cosa l'parseInt () è per lì? Ho semplificato a questa senza problemi ...

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

avrei commentato Nicks risposta, ma non ho abbastanza rep ancora.

Ho avuto questo stesso problema e sono stato in grado di risolverlo implementando l'interfaccia IValidatableObject nel mio modello di vista.

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

Il codice del rasoio è quindi ...

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

Questo funziona davvero bene. Se tento di usare [StringLength] invece poi il rendering HTML non è solo corretta. La convalida dovrebbe rendere come:

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

Con i StringLengthAttribute gli spettacoli HTML resi come ValidationSummary che non è corretto. La cosa divertente è che quando il validatore fallisce il presentare è ancora bloccata!

StringLength funziona alla grande, ho usato in questo modo:

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

o Basta usare RegularExpression senza StringLength:

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

ma per me al di sopra metodi ha dato errore nel display, perché avevo già campo NomeProdotto nel database che ha avuto più di 25 caratteri

così alla fine mi sono imbattuto in questo e questo Post e ha cercato di validate senza modello come questo :

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

questo ha risolto il mio problema, si può anche fare la convalida manualmente utilizzando jquery o utilizzando ModelState.AddModelError

speranza aiuta qualcuno.

So di essere molto in ritardo alla festa, ma ho finalmente scoperto come possiamo registrare il MaxLengthAttribute.

In primo luogo abbiamo bisogno di un validatore:

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

Niente di davvero speciale. Nel costruttore ci salva alcuni valori dall'attributo. Nel GetClientValidationRules abbiamo impostato una regola. ValidationType = "length" viene mappato data-val-length dal quadro. rule.ValidationParameters["max"] è per l'attributo data-val-length-max.

Ora, poiché si dispone di un validatore, avete solo bisogno di registrare in global.asax:

protected void Application_Start()
{
    //...

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

Et voilà, semplicemente funziona.

ho provato questo per tutti gli ingressi nel mio documento HTML (textarea, ingressi, ecc) che aveva la proprietà data-val-di lunghezza-max e funziona correttamente.

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

Questo può sostituire la MaxLength e la minLength

[StringLength(40, MinimumLength = 10 , ErrorMessage = "Name cannot be longer than 40 characters and less than 10")]
<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;
});
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top