2013-07-22 10 views
6

ho un elenco di Coppia di pulsanti di scelta (Sì/No):Come rendere necessaria una proprietà in base a più condizioni?

Q1.(Y)(N) 
Q2.(Y)(N) 
Q3.(Y)(N) 
Q4.(Y)(N) 

e ho una proprietà nel mio modello public string MedicalExplanation { get; set; }

Il mio obiettivo è quello di rendere Spiegazione necessaria se una qualsiasi delle radio il pulsante è stato impostato su true.

Il mio primo tentativo è stato quello di utilizzare [Required] ma non gestisce le condizioni.

poi ho deciso di utilizzare lo strumento di terze parti come MVC infallibile convalida ho usato in questo modo: [RequiredIf("Q1", true, ErrorMessage = "You must explain any \"Yes\" answers!")]

Ora il problema è che non so come farlo necessario se uno qualsiasi degli altri Q2, Q3, Q4 è selezionato.

Si prega di consulenza

risposta

15

Nel vostro ViewModel, creare un propery bool come questo:

public bool IsMedicalExplanationRequired 
{ 
    get 
    { 
     return Q1 || Q2 || Q3 || Q4; 
    } 
} 

Quindi, utilizzare l'attributo RequiredIf in questo modo:

[RequiredIf("IsMedicalExplanationRequired", true, ErrorMessage = "You must explain any \"Yes\" answers!")] 

UPDATE:

Se le proprietà Q1 - Q4 sono di tipo bool?, basta cambiare la proprietà IsMedicalExplanationRequired come di seguito:

public bool IsMedicalExplanationRequired 
{ 
    get 
    { 
     return Q1.GetValueOrDefault() || Q2.GetValueOrDefault() || Q3.GetValueOrDefault() || Q4.GetValueOrDefault(); 
    } 
} 
+0

nella mia domanda Q1, Q2, Q3, Q4 sono booleani (sì o no) quindi ricevo l'errore 'Operatore '||' non può essere applicato agli operandi di tipo "bool?" ' – meda

+0

Vedere la risposta aggiornata. – ataravati

+0

Ottimo! Tu il migliore ! haha! – meda

3

Ecco come ho fatto:

Per prima cosa ho creato un attributo di convalida personalizzato che ottiene una matrice di stringhe di campi per controllare passata:

public class ValidateAtLeastOneChecked : ValidationAttribute { 
    public string[] CheckBoxFields {get; set;} 
    public ValidateAtLeastOneChecked(string[] checkBoxFields) { 
     CheckBoxFields = checkBoxFields; 
    } 

    protected override ValidationResult IsValid(Object value, ValidationContext context) { 
     Object instance = context.ObjectInstance; 
     Type type = instance.GetType(); 

     foreach(string s in CheckBoxFields) { 
      Object propertyValue = type.GetProperty(s).GetValue(instance, null); 
      if (bool.Parse(propertyValue.ToString())) { 
       return ValidationResult.Success; 
      } 
     } 
     return new ValidationResult(base.ErrorMessageString); 
    } 
} 

Quindi lo uso in questo modo (sto usando i file di risorse per localizzare i miei messaggi di errore):

[ValidateAtLeastOneChecked(new string[] { "Checkbox1", "Checkbox2", "Checkbox3", "Checkbox4" }, ErrorMessageResourceType=typeof(ErrorMessageResources),ErrorMessageResourceName="SelectAtLeastOneTopic")] 
public bool Checkbox1{ get; set; } 
public bool Checkbox2{ get; set; } 
public bool Checkbox3{ get; set; } 
public bool Checkbox4{ get; set; } 

In realtà sta solo impostando l'errore sulla prima casella di controllo. Se si sta utilizzando l'evidenziazione css incorporata per evidenziare i campi per errore, è necessario modificarlo leggermente per farlo sembrare corretto, ma ho ritenuto che fosse una soluzione pulita che è stata riusabile e mi ha consentito di sfruttare il supporto per i file di risorse in attributi di validazione.

+0

questo è un buon approccio, proverò quando avrò la possibilità +1 – meda