2011-10-20 15 views
5

Come posso sostituire i valori di intervallo con i valori Web.Config in MVC3?Annotazioni dati - Come posso sostituire i valori Intervallo con i valori Web.Config in MVC3?

[Range(5, 20, ErrorMessage = "Initial Deposit should be between $5.00 and $20.00") 
public decimal InitialDeposit { get; set; } 

web.config:

<add key="MinBalance" value="5.00"/> 
<add key="MaxDeposit" value="20.00"/> 
+1

possibile duplicato di [Annotazione dati/Validazione e valori dinamici] (http://stackoverflow.com/questions/2122161/data-annotation-validation-and-dynamic-values) –

risposta

7

Sarà necessario creare un attributo personalizzato che eredita da RangeAttribute e l'attuazione di IClientValidatable.

public class ConfigRangeAttribute : RangeAttribute, IClientValidatable 
    { 
     public ConfigRangeAttribute(int Int) : 
      base 
      (Convert.ToInt32(WebConfigurationManager.AppSettings["IntMin"]), 
      Convert.ToInt32(WebConfigurationManager.AppSettings["IntMax"])) { } 

     public ConfigRangeAttribute(double Double) : 
      base 
      (Convert.ToDouble(WebConfigurationManager.AppSettings["DoubleMin"]), 
      Convert.ToDouble(WebConfigurationManager.AppSettings["DoubleMax"])) 
     { 
      _double = true; 
     } 

     private bool _double = false; 

     public override string FormatErrorMessage(string name) 
     { 
      return String.Format(ErrorMessageString, name, this.Minimum, this.Maximum); 
     } 

     public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
     { 
      var rule = new ModelClientValidationRule 
      { 
       ErrorMessage = FormatErrorMessage(this.ErrorMessage), 
       ValidationType = "range", 
      }; 
      rule.ValidationParameters.Add("min", this.Minimum); 
      rule.ValidationParameters.Add("max", this.Maximum); 
      yield return rule; 
     } 

     protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
     { 
      if (value == null) 
       return null; 

      if (String.IsNullOrEmpty(value.ToString())) 
       return null; 

      if (_double) 
      { 
       var val = Convert.ToDouble(value); 
       if (val >= Convert.ToDouble(this.Minimum) && val <= Convert.ToDouble(this.Maximum)) 
        return null; 
      } 
      else 
      { 
       var val = Convert.ToInt32(value); 
       if (val >= Convert.ToInt32(this.Minimum) && val <= Convert.ToInt32(this.Maximum)) 
        return null; 
      } 

      return new ValidationResult(
       FormatErrorMessage(this.ErrorMessage) 
      ); 
     } 
    } 

Esempio utilizzo:

[ConfigRange(1)] 
public int MyInt { get; set; } 

[ConfigRange(1.1, ErrorMessage = "This one has gotta be between {1} and {2}!")] 
public double MyDouble { get; set; } 

Il primo esempio restituirà il messaggio di errore predefinito, e il secondo restituirà il messaggio di errore personalizzato. Entrambi useranno i valori dell'intervallo definiti in web.config.

+0

Perfetto! Ha funzionato. Grazie mille! – rk1962

+0

Sei un genio! – rk1962

+0

È bello essere apprezzato. ; ^> Grazie e buona fortuna. – counsellorben

4

Non sarà in grado di farlo nella dichiarazione attributo la proprietà come i valori devono essere noti al momento della compilazione. Il modo più semplice che ho potuto vedere per fare ciò sarebbe derivare una classe di attributo da RangeAttribute e impostare i valori di proprietà da provenire da web.config nella classe derivata. Qualcosa di simile

public class RangeFromConfigurationAttribute : RangeAttribute 
{ 
    public RangeFromConfigurationAttribute() 
     : base(int.Parse(WebConfigurationManager.AppSettings["MinBalance"]), int.Parse(WebConfigurationManager.AppSettings["MaxDeposit"])) 
    { 

    } 
} 

consiglia di venire con un nome migliore però :)

+0

Grazie mille. Ho appena creato una classe con il codice sopra e non ha funzionato. Mi sto perdendo qualcosa? – rk1962

+0

Vedrò se riesco a mettere insieme un esempio, anche se il codice di counsellorben sembra funzionare - http://stackoverflow.com/users/624472/counsellorben –

+0

@Russ Cam, felice che qualcuno abbia notato il mio contributo. Anche se hai ancora i regali. ;) – counsellorben

1

Pensare ad alta voce qui, ma l'attributo ConfigRange impone che la configurazione deve essere presente affinché funzioni. Non puoi scrivere una classe statica in grado di leggere i tuoi valori da web.config, app.config o qualsiasi cosa tu ritenga opportuno e quindi utilizzare quella classe statica nell'attributo dell'intervallo esistente?

public static class RangeReader 
{ 
    public static double Range1 
    { 
     // Replace this with logic to read from config file 
     get { return 20.0d; } 
    }   
} 

Poi annotare la vostra proprietà con:

[Range(ConfigReader.Range1, 25.0d)] 

So che classi statiche sono cattivi e ci potrebbe essere una buona ragione per non fare questo, ma ho pensato che darò un andare.

+1

Penso di averlo provato prima e non ha funzionato. – rk1962

+0

Non ho riscontrato errori di compilazione con un modello di visualizzazione, ma non ho avuto la possibilità di verificarlo passando un modello di vista alla vista. Riesci a ricordare perché questo non ha funzionato? –

+0

Proverò di nuovo e ti faccio sapere il messaggio di errore. Grazie! – rk1962

Problemi correlati