72 Stimmen

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

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

Alle unsere Einstellungen sind derzeit einfache Schlüssel-Wert-Paare, aber es wäre nützlich, benutzerdefinierte Konfigurationsabschnitte zu erstellen, damit es offensichtlich ist, wenn zwei Werte zusammen geändert werden müssen oder wenn die Einstellungen für eine Umgebung geändert werden müssen.

Wie lassen sich benutzerdefinierte Konfigurationsabschnitte am besten erstellen, und gibt es beim Abrufen der Werte irgendwelche Besonderheiten zu beachten?

84voto

andynil Punkte 26978

Verwendung von Attributen, untergeordneten Konfigurationsabschnitten und Constraints

Es besteht auch die Möglichkeit, Attribute zu verwenden, die sich automatisch um das Klempnerhandwerk kümmern und die Möglichkeit bieten, auf einfache Weise Einschränkungen hinzuzufügen.

Ich präsentiere hier ein Beispiel aus dem Code, den ich selbst auf einer meiner Websites verwende. Mit einer Einschränkung gebe ich die maximale Menge an Speicherplatz vor, die ein einzelner 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 der 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>

Kindliche Elemente

Das untergeordnete Xml-Element E-Mail wird in der gleichen .cs-Datei wie die obige Datei erstellt. Hier habe ich Beschränkungen für den Anschluss hinzugefügt. Wenn dem Port ein Wert zugewiesen wird, der nicht in diesem Bereich liegt, beschwert sich die Laufzeit, wenn die Konfiguration geladen wird.

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 Sie

Um es dann praktisch im Code zu verwenden, müssen Sie nur das MailCenterConfigurationObject instanziieren, das dann automatisch lesen Sie die entsprechenden Abschnitte aus der web.config.

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

Prüfung auf Gültigkeit

Ich habe bereits erwähnt, dass sich die Laufzeitumgebung beschwert, wenn die Konfiguration geladen wird und einige Daten nicht den Regeln entsprechen, die Sie eingerichtet haben (z. B. in MailCenterConfiguration.cs). Ich neige dazu, diese Dinge so schnell wie möglich zu wissen, wenn meine Website gestartet wird. Eine Möglichkeit, dieses Problem zu lösen, besteht darin, die Konfiguration in _Global.asax.cx.Application_Start_ zu laden. Wenn die Konfiguration ungültig ist, werden Sie mit Hilfe einer Ausnahme darüber informiert. Ihre Website wird nicht gestartet und stattdessen werden Ihnen detaillierte Ausnahmeinformationen in der Gelber Bildschirm des Todes .

Global.asax.cs

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

16 Stimmen

Wie würden Sie den Code ändern, wenn Sie mehrere <mail>-Kinderelemente erwarten?

13voto

Ishmaeel Punkte 13903

Quick'n Dirty:

Erstellen Sie zunächst Ihre KonfigurationSektion y KonfigurationsElement 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];
        }
    }
}

Dann lassen Sie das Framework wissen, wie es Ihre Konfigurationsklassen behandeln soll in web.config :

<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 so verwenden:

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

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

5voto

LordHits Punkte 4994

Es gibt eine ausgezeichnete Beispiel auf MSDN mit ConfigurationCollection und .NET 4.5 für benutzerdefinierte Abschnitte in der web.config, die eine Liste von Konfigurationselementen enthält.

4voto

Die benutzerdefinierte Konfiguration ist eine sehr praktische Sache, und oft gibt es bei Anwendungen den Wunsch nach einer erweiterbaren Lösung.

Für .NET 1.1 lesen Sie bitte den Artikel http://aspnet.4guysfromrolla.com/articles/020707-1.aspx

Hinweis: Die obige Lösung funktioniert auch für .NET 2.0.

Für eine .NET 2.0-spezifische Lösung, lesen Sie bitte den Artikel http://aspnet.4guysfromrolla.com/articles/032807-1.aspx

3voto

John Downey Punkte 13394

Sie können dies mit Section Handlers erreichen. Einen grundlegenden Überblick darüber, wie man einen solchen schreibt, finden Sie unter http://www.codeproject.com/KB/aspnet/ConfigSections.aspx verweist jedoch auf app.config, was so ziemlich dasselbe wäre wie das Schreiben einer Datei zur Verwendung in web.config. Dies ermöglicht es Ihnen, im Wesentlichen Ihre eigenen XML-Baum in der Konfigurationsdatei haben und tun einige erweiterte Konfiguration.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X