Wie definiere ich benutzerdefinierte web.config-Abschnitte mit potenziellen untergeordneten Elementen und Attributen für die Eigenschaften?

69

Die Webanwendungen, die ich entwickle, erfordern häufig voneinander abhängige Konfigurationseinstellungen, und es gibt auch Einstellungen, die sich ändern müssen, wenn wir zwischen den einzelnen Umgebungen wechseln.

Alle unsere Einstellungen sind derzeit einfache Schlüssel-Wert-Paare. Es ist jedoch hilfreich, benutzerdefinierte Konfigurationsabschnitte zu erstellen, damit klar ist, wann zwei Werte zusammen geändert werden müssen oder wann sich die Einstellungen für eine Umgebung ändern müssen.

Was ist der beste Weg, um benutzerdefinierte Konfigurationsabschnitte zu erstellen, und müssen beim Abrufen der Werte besondere Überlegungen angestellt werden?

Dave Anderson
quelle

Antworten:

82

Verwenden von Attributen, untergeordneten Konfigurationsabschnitten und Einschränkungen

Es besteht auch die Möglichkeit, Attribute zu verwenden, die sich automatisch um die Installation kümmern, und die Möglichkeit zu bieten, Einschränkungen einfach hinzuzufügen.

Ich präsentiere hier ein Beispiel aus Code, den ich selbst auf einer meiner Websites verwende. Mit einer Einschränkung diktiere ich die maximale Menge an Speicherplatz, die ein Benutzer verwenden darf.

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

Dies wird in web.config wie folgt eingerichtet

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

Untergeordnete Elemente

Die untergeordnete XML-Element- Mail wird in derselben CS-Datei wie oben erstellt. Hier habe ich Einschränkungen für den Port hinzugefügt. Wenn dem Port ein Wert zugewiesen wird, der nicht in diesem Bereich liegt, wird die Laufzeit beim Laden der Konfiguration beanstandet.

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

Verwenden

Um es dann praktisch im Code zu verwenden, müssen Sie lediglich das MailCenterConfigurationObject instanziieren. Dadurch werden die relevanten Abschnitte automatisch aus web.config gelesen.

MailCenterConfiguration.cs

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

        return instance;
    }
}

AnotherFile.cs

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

Überprüfen Sie die Gültigkeit

Ich habe bereits erwähnt, dass sich die Laufzeit beim Laden der Konfiguration beschwert und einige Daten nicht den von Ihnen festgelegten Regeln entsprechen (z. B. in MailCenterConfiguration.cs). Ich möchte diese Dinge so schnell wie möglich wissen, wenn meine Website gestartet wird. Eine Möglichkeit, dies zu lösen, besteht darin, die Konfiguration in _Global.asax.cx.Application_Start_ zu laden. Wenn die Konfiguration ungültig ist, werden Sie mit einer Ausnahme darüber informiert. Ihre Website wird nicht gestartet und stattdessen werden Ihnen im gelben Bildschirm des Todes detaillierte Ausnahmeinformationen angezeigt .

Global.asax.cs

protected void Application_ Start(object sender, EventArgs e)
{
    MailCenterConfiguration.Instance;
}
Andynil
quelle
16
Wie würden Sie den Code ändern, wenn Sie mehrere untergeordnete <mail> -Elemente erwarten?
Kevin Le - Khnle
12

Quick'n Dirty:

Erstellen Sie zuerst Ihre ConfigurationSection- und ConfigurationElement- Klassen:

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

Lassen Sie dann das Framework wissen, wie Sie mit Ihren Konfigurationsklassen in web.config umgehen :

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

Und fügen Sie unten Ihren eigenen Abschnitt hinzu:

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

Dann können Sie es in Ihrem Code folgendermaßen verwenden:

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

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

Es gibt ein hervorragendes Beispiel für MSDN mit ConfigurationCollectionund .NET 4.5 für benutzerdefinierte Abschnitte in web.config, das eine Liste von Konfigurationselementen enthält.

LordHits
quelle
3

Sie können dies mit Abschnittshandlern erreichen. Unter http://www.codeproject.com/KB/aspnet/ConfigSections.aspx finden Sie eine grundlegende Übersicht zum Schreiben einer Datei. Sie bezieht sich jedoch auf app.config. Dies entspricht weitgehend dem Schreiben einer Datei zur Verwendung im Web. config. Auf diese Weise können Sie im Wesentlichen Ihren eigenen XML-Baum in der Konfigurationsdatei haben und eine erweiterte Konfiguration vornehmen.

John Downey
quelle
2

Die einfachste Methode, die ich gefunden habe, ist die Verwendung des Abschnitts appSettings .

  1. Fügen Sie der Web.config Folgendes hinzu:

    <appSettings>
        <add key="MyProp" value="MyVal"/>
    </appSettings>
    

  2. Zugriff von Ihrem Code

    NameValueCollection appSettings = ConfigurationManager.AppSettings;
    string myPropVal = appSettings["MyProp"];
    

Mike
quelle