2016-09-06 138 views
0

我想構建一個FloatValidatorAttribute。 在這個MSDN文章:https://msdn.microsoft.com/en-us/library/system.configuration.configurationvalidatorattribute(v=vs.110).aspxConfigurationValidatorBase驗證方法接收默認值

有一些例子。 「ProgrammableValidator」及其屬性示例是我想要的浮動驗證器。

我可以找到這個網站的唯一實質性的事情就是這個沒有答案的問題: Validation of double using System.Configuration validator

我也發現了這一點:https://social.msdn.microsoft.com/Forums/vstudio/en-US/6faf9c70-162c-499b-8d0c-0b1f19c7a24a/issues-with-custom-configuration-validator-and-attribute?forum=clr 那人有什麼聽起來像一個類似的問題,因爲我做的。但它對我沒有幫助

我的問題是來自web.config的值未正確傳遞給我創建的FloatValidator的Validate方法。

這是我的代碼:

class FloatValidator : ConfigurationValidatorBase 
{ 
    public float MinValue { get; private set; } 
    public float MaxValue { get; private set; } 

    public FloatValidator(float minValue, float maxValue) 
    { 
     MinValue = minValue; 
     MaxValue = maxValue; 
    } 

    public override bool CanValidate(Type type) 
    { 
     return type == typeof(float); 
    } 

    public override void Validate(object obj) 
    { 
     float value; 
     try 
     { 
      value = float.Parse(obj.ToString()); 
     } 
     catch (Exception) 
     { 
      throw new ArgumentException(); 
     } 

     if (value < MinValue) 
     { 
      throw new ConfigurationErrorsException($"Value too low, minimum value allowed: {MinValue}"); 
     } 

     if (value > MaxValue) 
     { 
      throw new ConfigurationErrorsException($"Value too high, maximum value allowed: {MaxValue}"); 
     } 
    } 
} 

屬性它自:

class FloatValidatorAttribute : ConfigurationValidatorAttribute 
{ 
    public float MinValue { get; set; } 
    public float MaxValue { get; set; } 

    public FloatValidatorAttribute(float minValue, float maxValue) 
    { 
     MinValue = minValue; 
     MaxValue = maxValue; 
    } 

    public override ConfigurationValidatorBase ValidatorInstance => new FloatValidator(MinValue, MaxValue); 
} 

配置元素它自:

public class Compound : ConfigurationElement 
{ 
    [ConfigurationProperty("name", IsRequired = true, IsKey = true)] 
    public string Name => this["name"] as string; 

    [ConfigurationProperty("abbreviation", IsRequired = true)] 
    public string Abbreviation => this["abbreviation"] as string; 

    [ConfigurationProperty("id", IsRequired = true)] 
    [IntegerValidator(ExcludeRange = false, MinValue = 0, MaxValue = int.MaxValue)] 
    public int Id => (int)this["id"]; 

    [ConfigurationProperty("factor", IsRequired = true)] 
    [FloatValidator(float.Epsilon, float.MaxValue)] 
    public float Factor => (float) this["factor"]; 
} 

下面是從web化合物元素的示例.config

<add name="Ozone" abbreviation="O3" id="147" factor="1.9957"/> 
    <add name="Particles smaller than 10 µm, Tapered Element Oscillating Microbalance measurement" abbreviation="PM10Teom" id="161" factor="1" /> 

我可以正確檢索這些值,並且可以將該因子應用於我正在處理的測量值。 但是,如果我應用FloatValidator,所有傳遞給類FloatValidator中Validate()的值都是0,所以我實際上無法驗證輸入。

謝謝你提前

回答

1

該框架似乎驗證了您的屬性的默認值。由於不存在默認值,因此使用default(float)。這就是爲什麼你看到一個調用Validate的地方,其中0通過。

由於驗證失敗,您不會看到後續調用。他們將包含您的配置中的相關值。

你應該爲Factor提供一個默認值:

[ConfigurationProperty("factor", IsRequired = true, DefaultValue = float.Epsilon)] 

同樣實際上是內置IntegerValidator -attribute用於Id -property的情況。如果使用不包含零的範圍,並且不應用默認值,則不會進行驗證。請參閱https://stackoverflow.com/a/2150643/1668425

+0

謝謝卡斯爾:) –

0

它似乎工作。

使用此的app.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <section name="CompoundConfiguration" type="ConsoleApplication2.CompoundConfigurationSection,ConsoleApplication2,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null" /> 
    </configSections> 
    <startup> 
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> 
    </startup> 
    <CompoundConfiguration> 
    <Compounds> 
     <add name="Particles smaller than 10 µm, Tapered Element Oscillating Microbalance measurement" abbreviation="PM10Teom" id="161" factor="1" /> 
     <add name="Ozone" abbreviation="O3" id="147" factor="1.9957" /> 
    </Compounds> 
    </CompoundConfiguration> 
</configuration> 

,並提供配置節的實現:

public class CompoundConfigurationSection : ConfigurationSection 
{ 
    [ConfigurationProperty("Compounds", IsDefaultCollection = false)] 
    [ConfigurationCollection(typeof(CompoundCollection), 
     AddItemName = "add", 
     ClearItemsName = "clear", 
     RemoveItemName = "remove")] 
    public CompoundCollection Compounds 
    { 
     get 
     { 
      return (CompoundCollection)base["Compounds"]; 
     } 
    } 
} 

隨着一個ElementCollection:

public class CompoundCollection : ConfigurationElementCollection 
{ 
    public CompoundCollection() 
    { 
    } 

    public Compound this[int index] 
    { 
     get { return (Compound)BaseGet(index); } 
     set 
     { 
      if (BaseGet(index) != null) 
      { 
       BaseRemoveAt(index); 
      } 
      BaseAdd(index, value); 
     } 
    } 

    public void Add(Compound serviceConfig) 
    { 
     BaseAdd(serviceConfig); 
    } 

    public void Clear() 
    { 
     BaseClear(); 
    } 

    protected override ConfigurationElement CreateNewElement() 
    { 
     return new Compound(); 
    } 

    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((Compound)element).Id; 
    } 

    public void Remove(Compound serviceConfig) 
    { 
     BaseRemove(serviceConfig.Id); 
    } 

    public void RemoveAt(int index) 
    { 
     BaseRemoveAt(index); 
    } 

    public void Remove(string name) 
    { 
     BaseRemove(name); 
    } 
} 

運行此主:

static void Main(string[] args) 
    { 
     var compounds = ConfigurationManager.GetSection("CompoundConfiguration"); 
    } 

給出與消息的異常:

Value too low, minimum value allowed: 1,401298E-45 

這我猜是預期的結果?

+0

我也收到異常 - 但即使值在允許的範圍內,我也會得到它。哪個是比float.Epsilon大,低於float.MaxValue 如果你在FloatValidator類的Validate方法上設置了一個斷點,你會看到你也獲得了0作爲參數。並與兩個示例化合物應該是1或1.9957 –