2013-01-11 2 views
5

Come è possibile creare un attributo di convalida personalizzato con convalida lato client senza implementare IClientValidatable?ASP.NET MVC: implementazione convalida lato client con attributo senza IClientValidatable

Come convalidare il lato client System.ComponentModel.DataAnnotations.RequiredAttribute?

La ragione per fare questo è perché sto usando oggetti da classi in un altro progetto come modelli nelle mie viste e non voglio aggiungere il riferimento System.Web.MVC a quel progetto.

EDIT per aggiungere ulteriori informazioni:

  • so che IClientValidatable viene utilizzato per aggiungere attributi personalizzati per il codice HTML da usare in seguito dalla convalida non invadente.

  • So che sarà necessario aggiungere il codice javascript per effettuare la convalida nel client .

Quello che non so è come utilizzare le informazioni dal l'attributo di convalida personalizzato per aggiungere gli attributi necessari per il codice HTML per la convalida discreto per lavorare.

Questo è il mio attributo di convalida personalizzato:

public class RequiredGuidAttribute : ValidationAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     Guid? guidValue = value as Guid?; 

     if (guidValue == null) 
      return false; 

     return guidValue != Guid.Empty; 
    } 
} 

Questa è la mia proprietà con l'attributo applicata:

[RequiredGuid(ErrorMessageResourceType = typeof(ClientOrderResources), ErrorMessageResourceName = "RequiredShippingMethod")] 
    public Guid ShippingMethodId 
    { 
     get { return GetProperty(ShippingMethodIdProperty); } 
     set { SetProperty(ShippingMethodIdProperty, value); } 
    } 

E finalmente sto rendendo un ingresso nascosto per quella proprietà nella vista utilizzando Html.HiddenFor.

Ora, come posso ottenere il messaggio di errore dall'attributo per applicarlo all'HTML? Dovrei farlo da solo usando Reflection o c'è un modo migliore?

E poi come posso dire a Html.HiddenFor di usare quell'informazione per aggiungere gli attributi necessari all'HTML?

risposta

0

Non è possibile avere una convalida personalizzata sul client a meno che non si implementi IClientValidatable. E per questo è anche necessario aggiungere script client.

http://msdn.microsoft.com/en-us/vs2010trainingcourse_aspnetmvccustomvalidation_topic3.aspx

+0

Mi dispiace, ma deve essere un modo, perché gli attributi di DataAnnotations sono riconosciuti dagli helper html e generano html con gli attributi richiesti per la convalida del client. So che dovrò aggiungere script client e questo non è un problema. – Marques

5

Abbiamo avuto un problema simile. Abbiamo un modello che utilizziamo per la creazione del nostro account che utilizza IClientValidatable sui suoi attributi personalizzati. Tuttavia, abbiamo creato un processo di creazione di un account batch all'esterno del sito Web in cui non siamo stati in grado di fare riferimento a System.Web.Mvc. Per questo motivo, quando abbiamo chiamato Validator.TryValidateObject, qualsiasi validatore personalizzato ereditato da IClientValidatable era semplicemente saltato.Ecco quello che stavamo lavorando con che non riusciva a validare al di fuori del nostro sito web:

public class AgeValidatorAttribute : ValidationAttribute, IClientValidatable 
{ 
    public int AgeMin { get; set; } 
    public int AgeMax { get; set; } 

    public override bool IsValid(object value) 
    { 
     //run validation 
    } 
} 

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var rule = new ModelClientValidationRule 
     { 
      ErrorMessage = ErrorMessageString, 
      ValidationType = "agevalidator" 
     }; 

     rule.ValidationParameters["agemin"] = AgeMin; 
     rule.ValidationParameters["agemax"] = AgeMax; 

     yield return rule; 
    } 

Rimozione System.Web.Mvc ci ha richiesto di rimuovere anche GetClientValidationRules e il riferimento IClientValidatable. Per fare questo e hanno la validazione lato client ancora, abbiamo dovuto creare una nuova classe:

public class AgeValidatorClientValidator : DataAnnotationsModelValidator<AgeValidatorAttribute> 
{ 
    private readonly string _errorMessage; 
    private readonly string _validationType; 

    public AgeValidatorClientValidator(ModelMetadata metadata, ControllerContext context, AgeValidatorAttribute attribute) 
     : base(metadata, context, attribute) 
    { 
     this._errorMessage = attribute.FormatErrorMessage(metadata.DisplayName); 
     this._validationType = "agevalidator"; 
    } 

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
    { 
     var rule = new ModelClientValidationRule 
     { 
      ErrorMessage = this._errorMessage, 
      ValidationType = this._validationType 
     }; 

     rule.ValidationParameters["agemin"] = base.Attribute.AgeMin; 
     rule.ValidationParameters["agemax"] = base.Attribute.AgeMax; 

     yield return rule; 
    } 
} 

Come si può vedere, lo fa essenzialmente la stessa cosa come una volta, è solo fatto utilizzando il DataAnnatotationsModelValidator piuttosto di IClientValidatable. C'è un altro passo che dobbiamo fare per attaccare in realtà la DataAnnotationsModelValidator al atttribute, e questo è fatto nel metodo Global.asax.cs Application_Start

DataAnnotationsModelValidatorProvider.RegisterAdapter( typeof(AgeValidatorAttribute), typeof(AgeValidatorClientValidator));

Ora è possibile utilizzare questo come si usa un normale attributo:

[AgeValidator(AgeMax = 110, AgeMin = 18, ErrorMessage = "The member must be between 18 and 110 years old")] 
public string DateOfBirth { get; set; } 

so che questa domanda è un anno vecchio, ma ho passato tutto il giorno ieri e la metà di oggi cercando di capire questo problema fuori. Quindi spero che questo aiuti qualcuno che si imbatte nello stesso problema se OP non ha ancora capito la risposta.

Nota: non ho incluso alcun javascript in questo articolo poiché non ha richiesto modifiche all'implementazione standard delle regole di convalida personalizzate utilizzando jQuery.Validate.

+1

Ci ho messo un po 'a capire che la classe Validator deve entrare in una libreria che ha ancora un riferimento a System.Web.Mvc, cioè non può sedersi nello stesso progetto della classe Attribute. Ma una volta che ho capito che funziona è un piacere. Molto utile. – bgx