Hinzufügen von benutzerdefinierten Konfigurationseinstellungen für eine (ASP) .NET-Anwendung

Seit der Veröffentlichung haben ASP.NET-Anwendungen und -Komponenten die Datei web.config aufgerufen, um alle für das Funktionieren erforderlichen Einstellungen zu laden. Das Hinzufügen von benutzerdefinierten Einstellungen, um einer Anwendung oder Komponente Flexibilität und Robustheit zu verleihen, ist jedoch nicht so einfach, wie die meisten möchten. In diesem Artikel erfahren Sie, wie Sie die erforderlichen Klassen schreiben, um XML-Konfigurationselemente zu verarbeiten und die darin enthaltenen Einstellungen in Ihrem Code zu verwenden.

Erneut veröffentlichtes Tutorial

Alle paar Wochen besuchen wir einige der Lieblingsbeiträge unserer Leser aus der gesamten Geschichte der Website. Dieses Tutorial wurde erstmals im November 2012 veröffentlicht.

Das .NET Framework bietet eine Vielzahl von Einstellungen, die in web.config konfiguriert werden können, um das Verhalten einer oder mehrerer integrierter Komponenten in der Anwendung zu ändern. Für einige Entwickler reicht es aus, nur die von .NET Framework bereitgestellten Einstellungen einzuhalten. Viele andere Entwickler müssen jedoch eine breitere Auswahl an Einstellungen steuern - entweder für Komponenten (von ihnen selbst oder von Dritten geschrieben) oder einfach für eine Reihe von Werten, die sie in ihrer gesamten Anwendung verwenden.

Mit der Datei web.config können Sie benutzerdefinierte Einstellungen mit der Element, erlaubt aber nichts anderes als einfache Schlüssel / Wert-Paare. Das folgende XML-Element ist ein Beispiel für eine Einstellung, die in enthalten ist :

Schlüssel- / Werteinstellungen können in vielen Situationen sicherlich hilfreich sein, aber Einstellungen sind für robuste oder komplexe Komponenten oder Einstellungen einfach nicht flexibel genug.

Zum Glück ermöglicht Microsoft Entwicklern das Schreiben von Klassen, die den programmgesteuerten Zugriff auf benutzerdefinierte Konfigurationseinstellungen in web.config hinzufügen.


Der Konfigurationsabschnitt

Einstellungen in web.config werden in Konfigurationsabschnitte kategorisiert. Zum Beispiel die Einstellungen in der Dieser Abschnitt bezieht sich auf ASP.NET-Einstellungen für Ihre Anwendung. Sie können das Authentifizierungsschema Ihrer App ändern sowie HTTP-Handler hinzufügen oder entfernen, um bestimmte Funktionen für bestimmte Dateitypen auszuführen. Das In diesem Abschnitt können Sie viele Einstellungen von IIS7 steuern, ohne direkten Zugriff auf IIS7 zu haben.

Ein Konfigurationsabschnitt ist für alle Einstellungen erforderlich, die nicht im enthalten sind Element. Es empfiehlt sich daher, die XML-Struktur Ihrer Konfigurationseinstellungen zu entwerfen, bevor Sie Code schreiben.

Die in diesem Lernprogramm als Beispiel verwendete Konfiguration bezieht sich auf eine Komponente, die RSS- oder Atom-Feeds abruft. Es wird keine Analyse ausgeführt, da dies den Rahmen dieses Tutorials sprengen würde. Anstatt die Liste der abzurufenden Feeds hart zu codieren, sucht die Komponente in ihrer Konfiguration nach Namen und URLs der abzurufenden Feeds. Die Komponente heißt FeedRetriever und die gewünschte XML-Struktur ihrer Konfiguration sieht folgendermaßen aus:

      

Das Element wird durch den Konfigurationsabschnitt definiert. In der Regel sollte ein Konfigurationsabschnitt den Namen der Komponente teilen, für die er entwickelt wurde. Das Elemente nur Kind ist das Element. Stellen Sie sich dieses Element als eine Sammlung von Feeds vor, da es mehrere enthält Elemente (denken Sie an die Add () - Methode, die die meisten Sammlungsobjekte haben). Die Wahl eines Elements namens "add" mag auf den ersten Blick seltsam erscheinen, aber das Das Element wird in der Mehrzahl der integrierten Konfigurationsabschnitte verwendet. Wenn Sie es hier verwenden, folgen Sie einfach den Entwurfspraktiken von Microsoft.

Diese Elemente verwenden die Attribute name, url und cache, um bestimmte Einstellungen für jeden Feed festzulegen. Natürlich sind die Namens- und URL-Attribute erforderlich, aber das Cache-Attribut ist nicht und sollte standardmäßig auf true gesetzt werden.

Die obige Konfiguration ist einfach. Das Das Element könnte so geändert werden, dass es ein anderes untergeordnetes Element enthält , Einstellungen enthalten, die für alle Feeds gelten würden. Das Elemente können auch zusätzliche Attribute wie cacheTime und requestFrequency verwenden, um zu steuern, wie lange ein Feed zwischengespeichert wird und wie oft er vom Remote-Host angefordert wird. Die einzige Grenze für die Erweiterbarkeit und Konfigurierbarkeit ist Ihre Vorstellungskraft.


Konfigurationshandler schreiben

Nach dem Entwerfen der XML-Struktur müssen Sie als Nächstes einen Konfigurationshandler schreiben, um die in XML definierten Einstellungen zu verarbeiten. Der Handler ist in erster Linie eine Klasse, die von System.Configuration.ConfigurationSection erbt. Sie enthält jedoch auch die Verwendung anderer Klassen, beispielsweise Klassen, die von System.Configuration.ConfigurationElement und System.Configuration.ConfigurationElementCollection abgeleitet sind.

Auf ConfigurationElement basierende Klassen repräsentieren einzelne Elemente. Es ist der Baustein eines Konfigurationsabschnitts. Typen, die von ConfigurationElementCollection abgeleitet sind, repräsentieren einfach Elemente, die mehr als einen Elementtyp enthalten. Aus der oben aufgeführten Konfiguration wird der Das Element wird durch eine Klasse dargestellt, die von ConfigurationElementCollection abgeleitet ist Elemente werden durch eine ConfigurationElement-basierte Klasse dargestellt.


Vertretung der Element

Sie beginnen mit dem Element durch Darstellung mit einer Klasse namens FeedElement (abgeleitet von ConfigurationElement). Diese Klasse und zukünftige konfigurationsbezogene Klassen befinden sich im Namespace FeedRetriever.Configuration.

Jedes ConfigurationElement-Objekt fungiert als Indexer für seine interne Sammlung von Eigenschaftswerten. Mit dieser internen Sammlung und den .NET-Attributen können Sie die Zuordnung vornehmen Attribute des Elements für die Eigenschaften der FeedElement-Klasse.

Der folgende Code ist der vollständige Code für die FeedElement-Klasse:

public class FeedElement: ConfigurationElement [ConfigurationProperty ("name", IsKey = true, IsRequired = true)] öffentliche Zeichenfolge Name get return (string) this ["name"];  set this ["name"] = Wert;  [ConfigurationProperty ("url", IsRequired = true, DefaultValue = "http: // localhost")] [RegexStringValidator (@ "https? \: // \ S +")] öffentliche Zeichenfolge Url get return (string) diese ["url"];  set this ["url"] = value;  [ConfigurationProperty ("cache", IsRequired = false, DefaultValue = true)] public bool Cache get return (bool) this ["cache"];  set this ["cache"] = value; 

Die ConfigurationElement-Klasse dient als Indexer für eine zugrunde liegende Sammlung von Konfigurationseigenschaften (daher die Indexer-Notation dieses [keyValue]). Wenn Sie das Schlüsselwort this verwenden und auf die zugrunde liegende Eigenschaft mit einem Zeichenfolgeschlüssel zugreifen, können Sie den Wert der Eigenschaft abrufen und festlegen, ohne dass ein privates Feld diese Daten enthalten muss. Die zugrunde liegende Eigenschaftssammlung speichert Daten als Typ Object. Daher müssen Sie den Wert als den entsprechenden Typ umwandeln, wenn Sie etwas damit tun wollen.

Die Eigenschaften, die XML-Attribute darstellen, sind mit ConfigurationPropertyAttribute-Attributen versehen. Der erste Parameter des ConfigurationPropertyAttribute-Attributs ist der Name des XML-Attributs, das im gefunden wird Element. Auf den ersten Parameter folgt eine Menge von beliebig vielen benannten Parametern. Die folgende Liste ist eine vollständige Liste der möglichen Parameter:

  • DefaultValue - Ruft den Standardwert für die dekorierte Eigenschaft ab oder legt diesen fest. Dieser Parameter
    ist nicht nötig.
  • IsDefaultCollection - Ruft einen Wert ab oder legt einen booleschen Wert fest, der angibt, ob die Eigenschaft festgelegt ist
    ist die Standardeigenschaftssammlung für die dekorierte Eigenschaft. Dieser Parameter ist
    nicht erforderlich, und der Standardwert ist false.
  • IsKey - Ruft einen booleschen Wert ab, der angibt, ob diese Eigenschaft eine Schlüsseleigenschaft ist, oder legt diesen Wert fest
    für das dekorierte elementeigentum. Dieser Parameter ist nicht erforderlich und sein Standardwert
    Wert ist falsch.
  • IsRequired - Ruft einen booleschen Wert ab, der angibt, ob das dekorierte Element angezeigt wird, oder legt diesen fest
    Eigenschaft ist erforderlich. Dieser Parameter ist nicht erforderlich und der Standardwert ist false.

Der Standardwert "http: // localhost" für die URL-Eigenschaft ist kein Fehler. Das .NET Framework gibt Ihnen außerdem die Möglichkeit, die Eigenschaften mit Validatorattributen zu dekorieren, z. B. RegexStringValidatorAttribute, das die Url-Eigenschaft schmückt. Dieser Prüfer übernimmt den Wert der URL-Eigenschaft und überprüft ihn anhand des regulären Ausdrucks, der für das Attribut bereitgestellt wird. Es überprüft jedoch auch die Url-Eigenschaft, bevor sie die Daten aus dem XML-Element enthält. Der Standardwert der Url-Eigenschaft ist eine leere Zeichenfolge, wenn ein FeedElement-Objekt zum ersten Mal erstellt wird. Eine leere Zeichenfolge wird nicht anhand des bereitgestellten regulären Ausdrucks geprüft, sodass der Prüfer eine ArgumentException auslöst, bevor Daten aus der XML-Datei geladen werden.

Es gibt zwei mögliche Problemumgehungen für dieses Problem. Beim ersten Ansatz wird der reguläre Ausdruck so geändert, dass leere Zeichenfolgen zulässig sind. Der zweite Ansatz weist der Eigenschaft einen Standardwert zu. In diesem speziellen Fall spielt es keine Rolle. Selbst mit einem Standardwert ist das URL-Attribut immer noch ein erforderliches Attribut im Element - Die Anwendung löst eine ConfigurationErrorsException aus, wenn ein Element hat kein URL-Attribut.

Der System.Configuration-Namespace enthält mehrere andere Validatorattribute, um die den Eigenschaften zugewiesenen Daten und den ihnen zugeordneten XML-Attributen zu überprüfen. Im Folgenden werden alle Validatorattribute im System.Configuration-Namespace aufgeführt:

  • CallbackValidatorAttribute - Stellt eine Zuordnung zwischen einem CallbackValidator-Objekt und dem zu überprüfenden Code bereit
    dynamische Überprüfung für einen Konfigurationswert.
  • IntegerValidatorAttribute - Überprüft die Verwendung eines IntegerValidator-Objekts, um festzustellen, ob der Konfigurationswert innerhalb oder außerhalb eines bestimmten Bereichs liegt.
  • LongValidatorAttribute - Überprüft die Verwendung eines LongValidator-Objekts, um festzustellen, ob der Konfigurationswert innerhalb oder außerhalb eines bestimmten Bereichs liegt.
  • PositiveTimeSpanValidatorAttribute - Überprüft die Verwendung eines PositiveTimeSpanValidator-Objekts auf positive TimeSpan-Konfigurationswerte.
  • RegexStringValidatorAttribute - Überprüft die Verwendung eines RegexStringValidator-Objekts, um festzustellen, ob der Konfigurationswert dem regulären Ausdruck entspricht.
  • StringValidatorAttribute - Überprüft die Verwendung eines StringValidator-Objekts, um sicherzustellen, dass der Konfigurationswert bestimmte Kriterien erfüllt, z. B. Länge der Zeichenfolge und ungültige Zeichen.
  • SubclassTypeValidatorAttribute - Überprüft die Verwendung eines SubclassTypeValidator-Objekts, um festzustellen, ob der Konfigurationswert von einem bestimmten Typ abgeleitet ist.
  • TimeSpanValidatorAttribute - Überprüft die Verwendung eines TimeSpanValidator-Objekts, um festzustellen, ob der Konfigurationswert innerhalb oder außerhalb eines bestimmten Bereichs liegt.

Mit Ausnahme des CallbackValidatorAttribute müssen Sie keine entsprechenden Prüferobjekte erstellen, die in Verbindung mit den Prüferattributen verwendet werden sollen. Die .NET-Laufzeitumgebung erstellt die entsprechenden Prüferobjekte für Sie, und die Attribute enthalten die erforderlichen Parameter zum Konfigurieren der Prüferobjekte.

Dieses kleine Stück Code ist alles, was zur programmatischen Darstellung von Einzelpersonen erforderlich ist Elemente. Der nächste Schritt besteht darin, eine Klasse zu schreiben, die das darstellt Element.


Eine Element-Collection-Klasse schreiben

Die XML-Darstellung des Element ist das einer Sammlung von Feedelementen. Ebenso die programmatische Darstellung der Element ist eine Sammlung von FeedElement-Objekten. Diese Klasse namens FeedElementCollection leitet sich von der abstrakten ConfigurationElementCollection-Klasse ab.

Die ConfigurationElementCollection-Klasse enthält mehrere Member, aber nur zwei sind als abstrakt markiert. Daher hat die einfachste ConfigurationElementCollection-Implementierung zwei Methoden:

  • CreateNewElement () - Erstellt ein neues ConfigurationElement-Objekt (in diesem FeedElement)
    Fall).
  • GetElementKey () - Ruft den Elementschlüssel für ein angegebenes Konfigurationselement ab (das
    Name-Eigenschaft von FeedElement-Objekten in diesem Fall.

Sehen Sie sich dazu den vollständigen Code für die FeedElementCollection-Klasse an:

[ConfigurationCollection (typeof (FeedElement))] öffentliche Klasse FeedElementCollection: ConfigurationElementCollection protected überschreibt ConfigurationElement. CreateNewElement () return new FeedElement ();  protected override object GetElementKey (ConfigurationElement-Element) return ((FeedElement) -Element) .Name; 

Ein ConfigurationCollectionAttribute verziert diese Auflistungsklasse. Der erste Parameter für das Attribut ist ein Type-Objekt - der Typ der Elemente, die die Auflistung enthält. In diesem Fall handelt es sich um den FeedElement-Typ. Nach dem Typparameter gibt es mehrere benannte Parameter, die Sie an das Attribut übergeben können. Diese sind unten aufgeführt:

  • AddItemName - Legt den Namen von fest Konfigurationselement. Zum Beispiel,
    Wenn Sie diese Einstellung als "Feed" festlegen, ist die Elemente in der
    zu ändernde Konfiguration .
  • ClearItemsName - Legt den Namen der Datei fest Konfigurationselement (verwendet)
    alle Artikel aus der Sammlung löschen).
  • RemoveItemName - Legt den Namen für das fest Konfigurationselement (verwendet)
    einen Artikel aus der Sammlung entfernen).

Wenn diese benannten Parameter leer bleiben, werden sie standardmäßig verwendet , , .


Schreiben der FeedRetreiverSection-Klasse

Die letzte Klasse mit dem Namen FeedRetrieverSection leitet sich von ConfigurationSection ab und repräsentiert die Element. Dies ist die einfachste Klasse der Konfigurationsklassen. Die einzige Anforderung, die sie erfüllen muss, ist der programmgesteuerte Zugriff auf die Element (die FeedElementCollection).

Öffentliche Klasse FeedRetrieverSection: ConfigurationSection [ConfigurationProperty ("feeds", IsDefaultCollection = true)] public FeedElementCollection Feeds get return (FeedElementCollection) this ["feeds"];  set this ["Feeds"] = Wert; 

Es handelt sich dabei um eine Eigenschaft des Typs FeedElementCollection, die als Feeds bezeichnet wird, und ist mit einem ConfigurationPropertyAttribute-Objekt versehen, das es dem Element.


Web.config ändern

Wenn der Konfigurations-Handler abgeschlossen ist, können Sie die entsprechenden Elemente zu web.config hinzufügen. Das Ein Abschnitt kann überall in der Datei verwendet werden, sofern er direkt vom Stammelement abhängt (das Element). Das Platzieren in einem anderen Konfigurationsabschnitt führt zu einem Fehler.

Der nächste Schritt ist das Hinzufügen von

Kindelement zu . Das
Element hat zwei Attribute von Interesse:

  • name - Der Name des Konfigurationsabschnittselements. In diesem Fall lautet der Name feedRetriever.
  • Typ - Der qualifizierte Name der Klasse, die dem Abschnitt zugeordnet ist, und falls erforderlich,
    Der Name der Assembly, in der sich die Klasse befindet. In diesem Fall der qualifizierte Name
    ist FeedRetriever.Configuration.FeedRetrieverSection. Wenn es sich in einem separaten befindet
    Assembly würde das Typattribut den Wert "FeedRetriever.Configuration.FeedRetrieverSection" haben,
    ", woher ist der Name der Assembly
    ohne die Winkelklammern.

Folgende

Element ist das, was Sie zu einer Datei web.config hinzufügen, unter , Wenn sich die Konfigurationsklassen nicht in einer separaten Assembly befinden (wie beim Codedownload):

Jetzt ist Ihre Anwendung ordnungsgemäß für die Verwendung der Klassen FeedRetrieverSection, FeedElementCollection und FeedElement konfiguriert, um Ihnen programmgesteuerten Zugriff auf die benutzerdefinierten Einstellungen zu gewähren Konfigurationsabschnitt in web.config. Wie können Sie also auf diese Einstellungen in Ihrem Code zugreifen??


Auf Konfigurationsdaten aus Code zugreifen

Der System.Configuration-Namespace enthält eine statische Klasse namens ConfigurationManager. Wenn Sie die In diesem Abschnitt, in dem Sie Ihre Verbindungszeichenfolgen ablegen, sind Sie zumindest mit ConfigurationManager vertraut. Es hat eine Methode namens GetSection (), die eine Zeichenfolge akzeptiert, die den Namen des abzurufenden Konfigurationsabschnitts enthält. Der folgende Code demonstriert dies (vorausgesetzt, System.Configuration steht oben in der Codedatei):

FeedRetrieverSection config = ConfigurationManager.GetSection ("feedRetriever") als FeedRetrieverSection;

Die GetSection () - Methode gibt einen Wert vom Typ Object zurück. Daher muss der Typ in den Typ des Handlers für diesen Abschnitt umgewandelt werden. Dieser Code ruft den Abschnitt mit dem Namen feedRetriever ab und wandelt das Ergebnis in FeedRetrieverSection um. Sobald Sie das Objekt haben, können Sie programmgesteuert auf Konfigurationsdaten zugreifen.

Um Ihnen eine Vorstellung davon zu geben, wie Konfigurationseinstellungen in Ihrer Komponente oder Anwendung verwendet werden können, ist der folgende Code eine grundlegende Implementierung der FeedRetriever-Komponente.

public class FeedRetriever public static FeedRetrieverSection _Config = ConfigurationManager.GetSection ("feedRetriever") als FeedRetrieverSection;
public static void GetFeeds () foreach (FeedElement feedEl in _Config.Feeds) // Anforderung anfordern HttpWebRequest request = (HttpWebRequest) WebRequest.Create (feedEl.Url); HttpWebResponse response = (HttpWebResponse) request.GetResponse (); if (response.StatusCode == HttpStatusCode.OK) Zeichenfolge feedData = String.Empty; using (StreamReader reader = neuer StreamReader (response.GetResponseStream ())) feedData = reader.ReadToEnd (); if (feedEl.Cache) // Dateiname der Zeichenfolge der Cache-Datei Dateiname = String.Format ("0 _ 1 .xml", feedEl.Name, DateTime.Now.Ticks); // Cache-Datei mit (StreamWriter Writer = neuer StreamWriter (@ "C: \" + Dateiname)) Writer.Write (feedData);

Zuerst wird eine statische Variable namens _Config vom Typ FeedRetreiverSection deklariert und durch Aufrufen von ConfigurationManager.GetSection () ein Wert zugewiesen. Das Festlegen der Variablen statisch ist eine Entwurfsentscheidung. Auf diese Weise haben alle Mitglieder der Klasse, entweder Instanz oder Static, Zugriff auf die Konfigurationseinstellungen, ohne mehrere Aufrufe von GetSection () durchführen zu müssen..

Wenn Sie den Abschnittshandler mit GetSection () abrufen, haben Sie vollständigen Zugriff auf Objekte, die von Ihren Handlerklassen erstellt wurden. Die erste Zeile von GetFeeds () ist eine für jede Schleife, die alle FeedElement-Objekte durchläuft, die in dem FeedElementCollection-Objekt enthalten sind, das von der Feeds-Eigenschaft zurückgegeben wird. Dadurch haben Sie direkten Zugriff auf diese FeedElement-Objekte. Dadurch können Sie einfach auf die Namen, URLs und Cache-Einstellungen der einzelnen Feeds zugreifen.

Bei jeder Iteration der Schleife stellt die Methode eine Anforderung mit der URL-Eigenschaft des FeedElement-Objekts. Wenn die Anforderung zu einem Erfolg führt, werden die Daten des Feeds abgerufen und in der Variablen feedData gespeichert. Dann überprüft der Code die Cache-Eigenschaft des FeedElement-Objekts, um zu bestimmen, ob der Feed zwischengespeichert werden soll oder nicht. Beim Zwischenspeichern des Feeds müssen Sie einen Dateinamen mithilfe der Name-Eigenschaft des FeedElement-Objekts und dem aktuellen Datum und der aktuellen Uhrzeit erstellen. Dann erstellt ein StreamWriter-Objekt die Datei und schreibt die Daten des Feeds in die Datei.

Wie Sie sehen können, ist die Verwendung der Konfigurations-Handler-Klassen der Schlüssel zum Abrufen und Verwenden benutzerdefinierter Einstellungen in web.config. Dies erfordert sicherlich mehr Zeit und Aufwand von Ihnen, macht es jedoch definitiv einfacher, Ihre Anwendung oder Komponente für sich selbst und andere Entwickler zu konfigurieren.


Verkaufen Sie Ihre .NET-Komponenten auf CodeCanyon!



Wussten Sie, dass wir eine .NET-Kategorie für CodeCanyon haben? Wenn Sie ein erfahrener .NET-Entwickler sind, verkaufen Sie Ihre Skripts / Komponenten / Steuerelemente nicht als Autor und verdienen Sie 40-70% von jedem Verkauf?

  • Folgen Sie uns auf Twitter oder abonnieren Sie den Nettuts + RSS-Feed für die besten Webentwicklungs-Tutorials im Web.