2011-10-20 5 views
5

Jak mogę zamienić wartości zakresów na wartości Web.Config w MVC3?Adnotacje danych - jak mogę zastąpić wartości zakresów wartościami Web.Config w 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

możliwe duplikat [/ Weryfikacji danych adnotacji i wartości dynamicznych] (http://stackoverflow.com/questions/2122161/data-annotation-validation-and-dynamic-values) –

Odpowiedz

7

Trzeba będzie utworzyć niestandardowy atrybut dziedziczenie z RangeAttribute i wykonawczych 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) 
      ); 
     } 
    } 

Przykład użycia:

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

Pierwszy przykład zwróci komunikat o błędzie domyślne, a drugi zwróci niestandardowy komunikat o błędzie. Oba będą używać wartości zakresu zdefiniowanych w pliku web.config.

+0

Idealny! Zadziałało. Dziękuję bardzo! – rk1962

+0

Jesteś geniuszem! – rk1962

+0

To wspaniale być docenianym. ; ^> Dzięki i powodzenia. – counsellorben

4

Nie będzie w stanie to zrobić w deklaracji atrybutu na nieruchomości jako wartości muszą być znane w czasie kompilacji. Najprostszym sposobem, w jaki mogłem to zrobić, byłoby wyprowadzenie klasy atrybutu z RangeAttribute i ustawienie wartości właściwości pochodzących z web.config w klasie pochodnej. Coś jak

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

    } 
} 

chcieć wymyślić lepszej nazwy chociaż :)

+0

Dziękuję bardzo. Właśnie stworzyłem klasę z powyższym kodem i nie zadziałało. Czy czegoś brakuje? – rk1962

+0

Zobaczę, czy mogę złożyć przykład, chociaż kod counsellorben wygląda, jakby działał - http://stackoverflow.com/users/624472/counsellorben –

+0

@Russ Cam, cieszę się, że ktoś zauważył mój wkład. Chociaż wciąż masz gadżety. ;) – counsellorben

1

Myślenie głośno tutaj, ale atrybut ConfigRange wymaga, aby konfiguracja była obecna, aby to działało. Nie możesz napisać klasy statycznej, która odczytałaby twoje wartości z web.config, app.config lub cokolwiek, co uważasz za stosowne, a następnie używa tej klasy statycznej w istniejącym atrybucie zasięgu?

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

Następnie opisywanie aĹ z:

[Range(ConfigReader.Range1, 25.0d)] 

wiem, że ćwiczenia statyczne są złe i nie może również być dobrym powodem tego nie robi, ale myślałem, że dam szansę.

+1

Myślę, że próbowałem tego wcześniej i to nie działało. – rk1962

+0

Nie miałem żadnych błędów kompilacji z modelem widoku, ale nie miałem szansy przetestować tego przez przekazanie modelu widoku do widoku. Czy pamiętasz, dlaczego to nie zadziałało? –

+0

Spróbuję ponownie i powiadomię o błędzie. Dzięki! – rk1962

Powiązane problemy