2010-08-27 5 views
10

J'ai créé une section de configuration personnalisée dans une bibliothèque de classes C# en héritant de ConfigurationSection. Je référence la bibliothèque de classes dans mon application web (aussi C#, ASP.NET), remplis les attributs appropriés et tout fonctionne bien. Le problème commence quand je commence à ajouter des validateurs.Pourquoi StringValidator échoue toujours pour la section de configuration personnalisée?

Par exemple, cette propriété:

[ConfigurationProperty("appCode", IsRequired = true)] 
    public string ApplicationCode 
    { 
     get 
     { 
      return (string)base["appCode"]; 
     } 
     set 
     { 
      base["appCode"] = value; 
     } 
    } 

Comme il fonctionne très bien, mais dès que j'ajoute ceci:

[StringValidator(MinLength=1)] 

Il bombes avec l'erreur suivante:

La valeur de la propriété 'appCode' n'est pas valide. L'erreur est la suivante: La chaîne doit contenir au moins 1 caractères.

Je reçois cette erreur même si une valeur valide appCode figure dans mon fichier web.config. Si je supprime le validateur, cela fonctionne parfaitement. Est-ce que quelqu'un sait comment contourner cela?

+0

J'ai lu que série, malheureusement, il n'explique pas pourquoi je reçois l'erreur. –

+1

Avez-vous essayé d'initialiser la propriété ApplicationCode avec une valeur par défaut (valide)? Il semble que la règle de validation échoue à un moment donné avant que la valeur ne soit lue dans le fichier de configuration. – Shackles

+0

Oui, et cela fonctionne très bien avec les valeurs par défaut. Cependant, tous les champs n'ont pas de valeurs par défaut valides/raisonnables, en particulier celles facultatives, donc c'est ennuyeux qu'il ne semble pas pouvoir s'initialiser à partir de la configuration. –

Répondre

3

j'ai pu contourner ce problème en utilisant une ConfigurationProperty explicite comme la clé de mes propriétés collection plutôt qu'une chaîne, selon la mise en œuvre suivante:

public class AssemblyElement : ConfigurationElement 
{ 
    private static readonly ConfigurationProperty _propAssembly; 
    private static readonly ConfigurationPropertyCollection _properties; 

    static AssemblyElement() 
    { 
     _propAssembly = new ConfigurationProperty("assembly", typeof(string), null, null, new StringValidator(1), ConfigurationPropertyOptions.IsKey | ConfigurationPropertyOptions.IsRequired); 
     _properties = new ConfigurationPropertyCollection(); 
     _properties.Add(_propAssembly); 
    } 

    internal AssemblyElement() { } 
    public AssemblyElement(string assemblyName) 
    { 
     this.Assembly = assemblyName; 
    } 

    [ConfigurationProperty("assembly", IsRequired = true, IsKey = true, DefaultValue = "")] 
    [StringValidator(MinLength = 1)] 
    public string Assembly 
    { 
     get { return (string)base[_propAssembly]; } 
     set { base[_propAssembly] = value; } 
    } 

    internal AssemblyName AssemblyName 
    { 
     get { return new AssemblyName(this.Assembly); } 
    } 

    protected override ConfigurationPropertyCollection Properties 
    { 
     get { return _properties; } 
    } 
} 

(Ce code est étroitement calqué sur la code reflété à partir de la classe d'élément de configuration AssemblyInfo Je souhaite toujours que je n'ai pas eu à dupliquer mes validations, mais au moins ce code me permet de spécifier une valeur par défaut vide tout en exigeant une valeur.)

+0

Vous avez raison, j'aimerais ne pas avoir à faire ça non plus. Je l'ai essayé cependant et cela fonctionne, alors merci. –

+0

J'ai passé une journée entière à lutter contre ce problème. Excellent - cela a fait l'affaire pour moi. –

3

On dirait que la réponse est en effet parce qu'ils n'ont pas de valeur par défaut. Cela semble étrange, alors si quelqu'un a une meilleure réponse, faites-le moi savoir et j'accepterai le leur.

2

I eu ce problème pendant un certain temps, puis je me suis rendu compte que les validateurs d'un ne pas pour faire l'attribut ou les éléments requis, ils sont pour les valider.

Pour rendre une propriété obligatoire, vous devez utiliser les propriétés IsRequired et ConfigrationPropertyOptions.IsRequired, par ex.

[ConfigurationProperty("casLogoutUrl", DefaultValue = null, IsRequired = true, Options = ConfigurationPropertyOptions.IsRequired)] 
[StringValidator(MinLength=10)] 

Ou (si vous utilisez l'api)

ConfigurationProperty casLoginUrl = new ConfigurationProperty("casLoginUrl", typeof(string), null, null, new StringValidator(1), ConfigurationPropertyOptions.IsRequired); 

Faire cela, le cadre de la configuration se chargera de la propriété elle-même étant nécessaire, et le validateur poignées de valider ce qui est de la valeur. Les validateurs ne sont pas destinés à rendre quelque chose nécessaire.

Cela fonctionne également sur les éléments pour rendre les éléments enfants requis. Par exemple. si vous créez une ConfigSection personnalisée avec des éléments enfants et que vous avez besoin d'un élément enfant. Toutefois, si vous créez un CustomValidator qui hérite de ConfigurationValidatorBase, vous devez utiliser ElementInformation.IsPresent, par exemple.

  public override void Validate(object value) 
     { 
      CredentialConfigurationElement element = (CredentialConfigurationElement)value; 
      if (!element.ElementInformation.IsPresent) 
       return; //IsRequired is handle by the framework, don't throw error here only throw an error if the element is present and it fails validation. 
      if (string.IsNullOrEmpty(element.UserName) || string.IsNullOrEmpty(element.Password)) 
       throw new ConfigurationErrorsException("The restCredentials element is missing one or more required Attribute: userName or password."); 
     } 

Longue histoire courte, il vous manque les options partie de votre attribut pour le rendre nécessaire et ne doit pas utiliser StringValidator (MinLength = 1) pour le rendre nécessaire. En fait, StringValidator (MinLength = 1) est complètement redondant.Si vous le faites requis, il est impossible que MinLength = 1 échoue sans que le défaut Required échoue en premier, car s'il est présent, il est garanti qu'il aura au moins 1 caractère.

Changer votre validateur

[ConfigurationProperty("appCode", IsRequired = true, Options=ConfigurationPropertyOptions.IsRequired)] 

fossé Puis la chaîne validateur.

1

La résolution du StringValidator peut se faire par l'un quelconque des éléments suivants:

  • Retrait MinLength arguments
  • Réglage MinLength = 0
  • Retrait du StringValidator Attribut
  • Ajout DefaultValue à l'attribut ConfigurationProperty

La définition Idéal pour la propriété est comme:

[ConfigurationProperty("title", IsRequired = true, DefaultValue = "something")] 
[StringValidator(InvalidCharacters = "[email protected]#$%^&*()[]{}/;’\"|\\" 
    , MinLength = 1 
    , MaxLength = 256)] 
public string Title 
{ 
    get { return this["title"] as string; } 
    set { this["title"] = value; } 
} 
Questions connexes