Så här lägger du till anpassade konfigurationsinställningar för en (ASP) .NET-applikation

Sedan dess släppt har ASP.NET applikationer och komponenter tittat på web.config-filen för att ladda alla inställningar som de behöver för att fungera. Att lägga till anpassade inställningar för att lägga till flexibilitet och robusthet till en applikation eller komponent är dock inte så rakt fram som de flesta vill. Denna artikel lär dig hur du skriver de nödvändiga klasserna för att hantera XML-konfigurationselement och använda de inställningar de innehåller i din kod.

Publicerad handledning

Varje par veckor besöker vi några av våra läsares favoritinlägg från hela webbplatsens historia. Denna handledning publicerades först i november 2012.

.NET Framework ger en mängd olika inställningar som kan konfigureras inom web.config för att ändra beteendet hos en eller flera inbyggda komponenter i programmet. För vissa utvecklare är det bara att hålla fast med inställningarna från .NET Framework. Men många fler utvecklare finner att de behöver styra en bredare samling inställningar - antingen för komponenter (skrivna av sig själva eller en tredje part), eller helt enkelt en uppsättning värden som de finner sig använda under hela deras tillämpning.

Web.config-filen tillåter dig att ställa in anpassade inställningar med element, men det tillåter inte något annat än enkla nyckel / värdepar. Följande XML-element är ett exempel på en inställning som finns i :

Key / Value inställningar kan säkert vara till hjälp under många omständigheter, men Inställningarna är helt enkelt inte tillräckligt flexibla för robusta eller komplexa komponenter eller inställningar.

Lyckligtvis tillåter Microsoft utvecklare att skriva klasser som lägger till programmatisk åtkomst till anpassade konfigurationsinställningar som finns i web.config.


Konfigurationsavsnittet

Inställningar inom web.config kategoriseras i konfigurationssektioner. Till exempel, de inställningar som finns i avsnittet gäller ASP.NET inställningar för din ansökan. Du kan ändra autentiseringsschemat för din app, samt lägga till eller ta bort HTTP-hanterare för att utföra specifika funktioner för specifika filtyper. De avsnittet kan du styra många av IIS7s inställningar utan att ha direkt tillgång till IIS7.

En konfigurationssektion krävs av alla inställningar som inte finns i element. Så det är en bra idé att utforma XML-strukturen för dina konfigurationsinställningar innan du skriver någon kod.

Konfigurationen som används som exempel i den här handledningen är för en komponent som hämtar RSS- eller Atom-flöden. Det gör ingen parsing, eftersom det ligger utanför handledningen. I stället för att hårdkodning listan över feeds för att hämta ser komponenten ut sin konfiguration för att innehålla namnen och webbadresserna för feedsna som ska hämtas. Komponenten heter FeedRetriever, och den önskade XML-strukturen i dess konfiguration ser ut så här:

      

De element definieras av konfigurationsdelen. Som regel bör en konfigurationssektion dela namnet på komponenten den är avsedd för. De Endast barnets barn är element. Tänk på detta element som en samling av flöden eftersom det innehåller flera element (tänk på Add () -metoden som de flesta samlingsobjekten har). Valet av att använda ett element som heter "add" kan tyckas konstigt först, men element används i de flesta inbyggda konfigurationssektionerna. Så här använder du det här helt enkelt följer de designprinciper som Microsoft har lagt fram.

Dessa element använder namn, url och cache attribut för att ställa in vissa inställningar för varje flöde. Naturligtvis krävs namn- och urlattributen, men cacheattributet är inte, och borde vara standard som sant.

Ovanstående konfiguration är enkel. De Elementet kan modifieras för att innehålla ett annat barn, kallat , att innehålla inställningar som skulle gälla för alla flöden. De element kan också använda ytterligare attribut, till exempel cacheTime och requestFrequency, för att kontrollera hur länge ett flöde cachas och hur ofta det begärs från fjärrvärden. Den enda gränsen för förlängbarhet och konfigurerbarhet är din fantasi.


Skriva konfigurationshanteraren

Efter att ha utformat XML-strukturen är nästa steg att skriva en konfigurationshanterare för att bearbeta de inställningar som definieras i XML. Hanteraren är i första hand en klass som ärver från System.Configuration.ConfigurationSection, men det innehåller också användningen av andra klasser - som klasser som härrör från System.Configuration.ConfigurationElement och System.Configuration.ConfigurationElementCollection.

Klasser baserade på ConfigurationElement representerar enskilda element; Det är byggstenen i en konfigurationssektion. Typer som härrör från ConfigurationElementCollection representerar helt enkelt element som innehåller mer än en typ av element. Från konfigurationen som anges ovan, element representeras av en klass som härrör från ConfigurationElementCollection och Elementen representeras av en ConfigurationElement-baserad klass.


Representerar Element

Du börjar med element genom att representera det med en klass som heter FeedElement (härledd från ConfigurationElement). Den här klassen och framtida konfigurationsrelaterade klasser bor i namnet FeedRetriever.Configuration.

Varje ConfigurationElement-objekt fungerar som en index för sin interna samling av egenskapsvärden. Det är den här interna samlingen, tillsammans med .NET-attribut, som gör att du kan kartlägga elementets attribut till egenskaperna hos FeedElement-klassen.

Följande kod är den fullständiga koden för FeedElement-klassen:

public class FeedElement: ConfigurationElement [ConfigurationProperty ("namn", IsKey = true, IsRequired = true)] allmän sträng Namn get return (string) this ["name"];  sätta this ["name"] = value;  [ConfigurationProperty ("url", IsRequired = true, DefaultValue = "http: // localhost")] [RegexStringValidator (@ "https? \: // \ S +")] offentlig sträng Url get return detta [ "uRL"];  sätta this ["url"] = value;  [ConfigurationProperty ("cache", IsRequired = false, DefaultValue = true)] allmän boolcache get return (bool) this ["cache"];  sätta this ["cache"] = value; 

Klassen ConfigurationElement fungerar som en indexerare till en underliggande samling av konfigurationsegenskaper (därav indexeringsbeteckningen för denna [keyValue]). Genom att använda detta nyckelord och få tillgång till den underliggande egenskapen med en strängnyckel kan du få och ställa in egenskapens värde utan att behöva ha ett privatfält för att innehålla den data. Den underliggande egenskapsuppsamlingen lagrar data som typ Objekt; Därför måste du kasta värdet som lämplig typ om du vill göra något med det.

Egenskaperna som representerar XML-attribut är dekorerad med attributen ConfigurationPropertyAttribute. Den första parametern för attributet ConfigurationPropertyAttribute är namnet på XML-attributet som finns i element. Efter den första parametern är en uppsättning av några antal namngivna parametrar. Följande lista är en komplett lista över möjliga parametrar:

  • DefaultValue - Hämtar eller ställer in standardvärdet för den inredda egenskapen. Denna parameter
    behövs inte.
  • IsDefaultCollection - Gets eller en sätter ett booleskt värde som anger om egendomen
    är den ursprungliga egendomssamlingen för den inredda egendomen. Denna parameter är
    inte nödvändigt, och standard är felaktigt.
  • IsKey - Hämtar eller anger ett booleskt värde som anger om den här egenskapen är en nyckelegenskap
    för den dekorerade elementegenskapen. Denna parameter är inte nödvändig, och dess standard
    värdet är falskt.
  • IsRequired - Går eller ställer in ett booleskt värde som anger om det dekorerade elementet
    egendom krävs. Denna parameter är inte nödvändig, och dess standardvärde är felaktigt.

Standardvärdet för "http: // localhost" för egenskapen Url är inte ett fel. .NET Framework ger dig också möjlighet att dekorera egenskaperna med valideringsattribut - till exempel RegexStringValidatorAttribute som dekorerar Url-egenskapen. Denna validator tar värdet av Url-egenskapen och validerar det mot det reguljära uttrycket som tillhandahålls till attributet; Det validerar dock egenskapen Url innan den innehåller data från XML-elementet. Standardvärdet för Url-egenskapen är en tom sträng när ett FeedElement-objekt skapas först. En tom sträng validerar inte mot det angivna reguljära uttrycket, så validatorn kastar en ArgumentException innan data laddas från XML-filen.

Det finns två möjliga lösningar för detta problem. Den första metoden ändrar det reguljära uttrycket för att tillåta tomma strängar. Det andra tillvägagångssättet tilldelar ett standardvärde till egenskapen. Det spelar ingen roll i det här speciella fallet. Även med ett standardvärde är urlattributet fortfarande ett obligatoriskt attribut i element - programmet kastar en ConfigurationErrorsException om en Elementet har inte ett urlattribut.

Det finns flera andra validatorattribut i System.Configuration namespace för att validera data som tilldelas egenskaper och XML-attributen de kartlägger. Nedan listas alla valideringsattributen i namnfältet System.Configuration:

  • CallbackValidatorAttribute - Ger en koppling mellan ett CallbackValidator-objekt och koden som ska valideras - tillåter
    dynamisk validering för ett konfigurationsvärde.
  • IntegerValidatorAttribute - Validerar med ett IntegerValidator-objekt för att bestämma om konfigurationsvärdet faller inom eller utanför ett visst område.
  • LongValidatorAttribute - Validerar med ett LongValidator-objekt för att bestämma om konfigurationsvärdet faller inom eller utanför ett visst område.
  • PositiveTimeSpanValidatorAttribute - Validerar med ett positivtTimeSpanValidator-objekt för positiva TimeSpan-konfigurationsvärden.
  • RegexStringValidatorAttribute - Validerar med ett RegexStringValidator-objekt för att bestämma om konfigurationsvärdet följer det reguljära uttrycket.
  • StringValidatorAttribute - Validerar med ett StringValidator-objekt för att säkerställa att konfigurationsvärdet uppfyller vissa kriterier - t.ex. stränglängd och ogiltiga tecken.
  • SubclassTypeValidatorAttribute - Validerar med ett SubclassTypeValidator-objekt för att bestämma om konfigurationsvärdet härrör från en given typ.
  • TimeSpanValidatorAttribute - Validerar med ett TimeSpanValidator-objekt för att bestämma om konfigurationsvärdet faller inom eller utanför ett visst område.

Med undantag för CallbackValidatorAttribute behöver du inte skapa motsvarande validatorobjekt att använda tillsammans med validatorattributen. .NET runtime skapar lämpliga validatorobjekt för dig, och attributen innehåller de nödvändiga parametrarna för att konfigurera validatorobjekten.

Denna lilla bit av kod är allt som krävs för att programmera individuellt element. Nästa steg är att skriva en klass som representerar element.


Skriva en Element Collection Class

XML-representationen av elementet är en samling av matningselement. På samma sätt, den programmatiska representationen av elementet är en samling av FeedElement-objekt. Denna klass, som heter FeedElementCollection, härleds från den abstrakta ConfigurationElementCollection-klassen.

Klassen ConfigurationElementCollection innehåller flera medlemmar, men endast två är markerade som abstrakta. Således har det enklaste KonfigurationsElementCollection-genomförandet två metoder:

  • CreateNewElement () - Skapar ett nytt ConfigurationElement-objekt (FeedElement i detta
    fall).
  • GetElementKey () - Hämtar elementnyckeln för ett visst konfigurationselement (
    Namn egenskap av FeedElement objekt i det här fallet).

Med det i åtanke, se den fullständiga koden för klassen FeedElementCollection nedan:

[ConfigurationCollection (typeof (FeedElement)) offentlig klass FeedElementCollection: ConfigurationElementCollection protected override ConfigurationElement CreateNewElement () returnera nytt FeedElement ();  skyddad överstyrning objekt GetElementKey (ConfigurationElement element) return ((FeedElement) element) .Name; 

Ett ConfigurationCollectionAttribute dekorerar denna samlingsklass. Den första parametern till attributet är ett typobjekt - vilken typ av objekt samlingen innehåller. I det här fallet är det FeedElement-typen. Efter typparametern finns flera namngivna parametrar kan du skicka till attributet. Dessa listas nedan:

  • AddItemName - Ställer in namnet på konfigurationselement. Till exempel,
    Om du ställer in detta som "feed" skulle du behöva element i
    konfiguration som ska ändras till .
  • ClearItemsName - Ställer in namnet på konfigurationselement (används
    för att rensa alla objekt från samlingen).
  • RemoveItemName - Ställer in namnet för konfigurationselement (används
    för att ta bort ett objekt från samlingen).

Om du lämnar dessa namngivna parametrar ska du blanka dem till , , .


Skrivning av FeedRetreiverSection Class

Den slutliga klassen, som heter FeedRetrieverSection, härrör från ConfigurationSection och representerar element. Detta är den enklaste klassen av konfigurationsklasserna, eftersom det enda kravet måste mötas är att tillhandahålla programmatisk åtkomst till elementet (FeedElementCollection).

public class FeedRetrieverSection: ConfigurationSection [ConfigurationProperty ("feeds", IsDefaultCollection = true)] offentliga FeedElementCollection-flöden få return (FeedElementCollection) detta ["feeds"];  set this ["feeds"] = värde; 

Det är en egenskap, av typen FeedElementCollection och kallas Feeds, är dekorerad med ett ConfigurationPropertyAttribute - kartlägger det till element.


Ändra web.config

När konfigurationshanteraren är klar kan du lägga till lämpliga element för web.config. De sektionen kan gå någonstans i filen så länge det är en direkt nedstigning av rotelementet (den element). Om du placerar det i en annan konfigurationssektion resulterar ett fel.

Nästa steg är att lägga till en

barnelement till . De
elementet har två attribut av intresse:

  • namn - namnet på konfigurationssektionselementet. I det här fallet är namnet feedRetriever.
  • typ - Det kvalificerade namnet på den klass som är associerad med avsnittet, och vid behov,
    namnet på församlingen klassen ligger i. I det här fallet är det kvalificerade namnet
    är FeedRetriever.Configuration.FeedRetrieverSection. Om den ligger i en separat
    montering, skulle typattributet ha ett värde av "FeedRetriever.Configuration.FeedRetrieverSection,
    ", var är namnet på församlingen
    utan vinkelbeslagen.

Det följande

Elementet är det du lägger till i en web.config-fil, under , när konfigurationsklasserna inte bor i en separat enhet (som det är fallet i kodnedladdningen):

Nu är din ansökan korrekt konfigurerad för att använda FeedRetrieverSection, FeedElementCollection och FeedElement-klasserna för att ge dig programmatisk åtkomst till de anpassade inställningarna som finns i konfigurationssektionen i web.config. Så hur får du tillgång till dessa inställningar från din kod?


Åtkomst till konfigurationsdata från kod

Navnet System.Configuration innehåller en statisk klass som heter ConfigurationManager. Om du använder avsnittet för att hysa dina anslutningssträngar, är du minst bekant med ConfigurationManager. Den har en metod som heter GetSection (), som accepterar en sträng som innehåller namnet på konfigurationsdelen för att hämta. Följande kod visar detta (antar att du använder System.Configuration är högst upp i kodfilen):

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

Metoden GetSection () returnerar ett värde av typen Objekt, så det måste kastas till vilken typ som handlaren är för den delen. Denna kod hämtar avsnittet namnet feedRetriever och kastar resultatet som FeedRetrieverSection. När du har objektet kan du börja med att få tillgång till konfigurationsdata programmerat.

För att ge dig en uppfattning om hur konfigurationsinställningar kan användas inom din komponent eller applikation är följande kod en mycket grundläggande implementering av FeedRetriever-komponenten.

offentliga klass FeedRetriever offentliga statiska FeedRetrieverSection _Config = ConfigurationManager.GetSection ("feedRetriever") som FeedRetrieverSection;
public static void GetFeeds () foreach (FeedElement feedEl i _Config.Feeds) // göra förfrågan HttpWebRequest request = (HttpWebRequest) WebRequest.Create (feedEl.Url); HttpWebResponse response = (HttpWebResponse) request.GetResponse (); om (response.StatusCode == HttpStatusCode.OK) string feedData = String.Empty; använder (StreamReader reader = new StreamReader (response.GetResponseStream ())) feedData = reader.ReadToEnd (); om (feedEl.Cache) // filnamn för cachen filsträng filename = String.Format ("0 _ 1 .xml", feedEl.Name, DateTime.Now.Ticks); // cachefil med (StreamWriter writer = nytt StreamWriter (@ "C: \" + filnamn)) writer.Write (feedData);

Först deklareras en statisk variabel som heter _Config, av typen FeedRetreiverSection, och tilldelas ett värde genom att ringa ConfigurationManager.GetSection (). Att göra variabeln statisk är ett designval. Genom att göra så skulle alla medlemmar i klassen, antingen instans eller statisk, ha tillgång till konfigurationsinställningarna utan att behöva göra flera samtal till GetSection ().

När du hämtar sektionshanteraren med GetSection () har du fullständig tillgång till objekt som skapats från dina hanterarklasser. Den första raden av GetFeeds () är en för varje slinga som slingrar igenom alla FeedElement-objekt som ingår i FeedElementCollection-objektet som returneras av egenskapen Feeds. Detta ger dig direkt tillgång till dessa FeedElement-objekt - vilket gör det enkelt att komma åt varje flödes namn, URL och cache-inställningar.

Under varje iteration av slingan gör metoden en förfrågan med hjälp av FeedElement-objektets Url-egenskap. Om förfrågan resulterar i en framgång, hämtas foderets data och lagras i varianten feedData. Då kontrollerar koden feedElement-objektets Cache-egenskap för att avgöra huruvida cachen ska cachas eller ej. Caching i foderet innebär att man konstruerar ett filnamn med hjälp av FeedElement-objektets namnegenskap och aktuellt datum och tidpunkt. Då skapar ett StreamWriter-objekt filen och skriver matarens data till den.

Som du kan se är användarklasserna nyckelkod för att hämta och använda anpassade inställningar som finns i web.config. Det kräver säkert mer tid och ansträngning från dig, men det gör definitivt din applikation eller komponent mycket lättare att konfigurera för dig själv och andra utvecklare.


Sälj dina .NET-komponenter på CodeCanyon!



Visste du att vi har en .NET-kategori på CodeCanyon. Om du är en skicklig. NET dev, varför inte sälja dina skript / komponenter / kontroller som författare och tjäna 40-70% av varje försäljning?

  • Följ oss på Twitter, eller prenumerera på Nettuts + RSS-flödet för de bästa webbutvecklingsstudierna på webben.