72 votes

Comment puis-je définir des sections web.config personnalisées avec des éléments enfants potentiels et des attributs pour les propriétés ?

Les applications web que je développe nécessitent souvent des paramètres de configuration co-dépendants et il y a aussi des paramètres qui doivent changer lorsque nous nous déplaçons entre chacun de nos environnements.

Tous nos paramètres sont actuellement de simples paires clé-valeur, mais il serait utile de créer des sections de configuration personnalisées pour qu'il soit évident que deux valeurs doivent être modifiées ensemble ou que les paramètres doivent être modifiés pour un environnement.

Quelle est la meilleure façon de créer des sections de configuration personnalisées et y a-t-il des considérations particulières à prendre en compte lors de la récupération des valeurs ?

84voto

andnil Points 8179

Utilisation des attributs, des sections de configuration enfant et des contraintes

Il est également possible d'utiliser des attributs qui prennent automatiquement en charge la plomberie, tout en offrant la possibilité d'ajouter facilement des contraintes.

Je présente ici un exemple de code que j'utilise moi-même dans un de mes sites. Avec une contrainte, je dicte la quantité maximale d'espace disque qu'un utilisateur est autorisé à utiliser.

MailCenterConfiguration.cs :

namespace Ani {

    public sealed class MailCenterConfiguration : ConfigurationSection
    {
        [ConfigurationProperty("userDiskSpace", IsRequired = true)]
        [IntegerValidator(MinValue = 0, MaxValue = 1000000)]
        public int UserDiskSpace
        {
            get { return (int)base["userDiskSpace"]; }
            set { base["userDiskSpace"] = value; }
        }
    }
}

Ceci est configuré dans le web.config comme suit

<configSections>
    <!-- Mailcenter configuration file -->
    <section name="mailCenter" type="Ani.MailCenterConfiguration" requirePermission="false"/>
</configSections>
...
<mailCenter userDiskSpace="25000">
    <mail
     host="my.hostname.com"
     port="366" />
</mailCenter>

Éléments enfants

L'élément xml enfant courrier électronique est créé dans le même fichier .cs que celui ci-dessus. Ici, j'ai ajouté des contraintes sur le port. Si le port est assigné à une valeur qui n'est pas dans cette plage, le runtime se plaindra lorsque la configuration sera chargée.

MailCenterConfiguration.cs :

public sealed class MailCenterConfiguration : ConfigurationSection
{
    [ConfigurationProperty("mail", IsRequired=true)]
    public MailElement Mail
    {
        get { return (MailElement)base["mail"]; }
        set { base["mail"] = value; }
    }

    public class MailElement : ConfigurationElement
    {
        [ConfigurationProperty("host", IsRequired = true)]
        public string Host
        {
            get { return (string)base["host"]; }
            set { base["host"] = value; }
        }

        [ConfigurationProperty("port", IsRequired = true)]
        [IntegerValidator(MinValue = 0, MaxValue = 65535)]
        public int Port
        {
            get { return (int)base["port"]; }
            set { base["port"] = value; }
        }

Utilisez

Pour l'utiliser de manière pratique dans le code, il suffit d'instancier le MailCenterConfigurationObject. automatiquement lire les sections pertinentes du web.config.

MailCenterConfiguration.cs

private static MailCenterConfiguration instance = null;
public static MailCenterConfiguration Instance
{
    get
    {
        if (instance == null)
        {
            instance = (MailCenterConfiguration)WebConfigurationManager.GetSection("mailCenter");
        }

        return instance;
    }
}

AutreFichier.cs

public void SendMail()
{
    MailCenterConfiguration conf = MailCenterConfiguration.Instance;
    SmtpClient smtpClient = new SmtpClient(conf.Mail.Host, conf.Mail.Port);
}

Contrôle de la validité

J'ai mentionné précédemment que le runtime se plaint lorsque la configuration est chargée et que certaines données ne sont pas conformes aux règles que vous avez mises en place (par exemple dans MailCenterConfiguration.cs). J'ai tendance à vouloir connaître ces choses le plus tôt possible lorsque mon site démarre. Une façon de résoudre ce problème est de charger la configuration dans _Global.asax.cx.Application_Start_, si la configuration n'est pas valide, vous en serez informé au moyen d'une exception. Votre site ne démarrera pas et, à la place, des informations détaillées sur l'exception vous seront présentées dans la fenêtre de l'application. Écran jaune de la mort .

Global.asax.cs

protected void Application_ Start(object sender, EventArgs e)
{
    MailCenterConfiguration.Instance;
}

16 votes

Comment modifieriez-vous le code si vous prévoyez plusieurs éléments enfants <mail> ?

13voto

Ishmaeel Points 7720

Quick'n Dirty :

Créez d'abord votre ConfigurationSection y ConfigurationElement classes :

public class MyStuffSection : ConfigurationSection
{
    ConfigurationProperty _MyStuffElement;

    public MyStuffSection()
    {
        _MyStuffElement = new ConfigurationProperty("MyStuff", typeof(MyStuffElement), null);

        this.Properties.Add(_MyStuffElement);
    }

    public MyStuffElement MyStuff
    {
        get
        {
            return this[_MyStuffElement] as MyStuffElement;
        }
    }
}

public class MyStuffElement : ConfigurationElement
{
    ConfigurationProperty _SomeStuff;

    public MyStuffElement()
    {
        _SomeStuff = new ConfigurationProperty("SomeStuff", typeof(string), "<UNDEFINED>");

        this.Properties.Add(_SomeStuff);
    }

    public string SomeStuff
    {
        get
        {
            return (String)this[_SomeStuff];
        }
    }
}

Ensuite, indiquez au framework comment gérer vos classes de configuration dans le fichier web.config :

<configuration>
  <configSections>
    <section name="MyStuffSection" type="MyWeb.Configuration.MyStuffSection" />
  </configSections>
  ...

Et en fait, ajoutez votre propre section ci-dessous :

  <MyStuffSection>
    <MyStuff SomeStuff="Hey There!" />
  </MyStuffSection>

Vous pouvez alors l'utiliser dans votre code ainsi :

MyWeb.Configuration.MyStuffSection configSection = ConfigurationManager.GetSection("MyStuffSection") as MyWeb.Configuration.MyStuffSection;

if (configSection != null && configSection.MyStuff != null)
{
    Response.Write(configSection.MyStuff.SomeStuff);
}

5voto

LordHits Points 3006

Il y a un excellent exemple sur MSDN en utilisant ConfigurationCollection et .NET 4.5 pour les sections personnalisées dans web.config qui ont une liste d'éléments de configuration.

4voto

La configuration personnalisée est très pratique et les applications se terminent souvent par la demande d'une solution extensible.

Pour .NET 1.1, veuillez vous référer à l'article http://aspnet.4guysfromrolla.com/articles/020707-1.aspx

Remarque : la solution ci-dessus fonctionne également pour .NET 2.0.

Pour la solution spécifique à .NET 2.0, veuillez vous référer à l'article http://aspnet.4guysfromrolla.com/articles/032807-1.aspx

3voto

John Downey Points 6729

Vous pouvez y parvenir grâce aux gestionnaires de section. Vous trouverez un aperçu de base sur la façon d'en écrire un à l'adresse suivante http://www.codeproject.com/KB/aspnet/ConfigSections.aspx Cependant, il fait référence à app.config, ce qui revient à peu près au même que d'en écrire un pour l'utiliser dans web.config. Cela vous permettra essentiellement d'avoir votre propre arbre XML dans le fichier de configuration et de réaliser une configuration plus avancée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X