2009-07-18 14 views
9

Desidero leggere la sezione XML personalizzata da app.config di un servizio Windows C#.Come leggere l'XML personalizzato da app.config?

Come faccio?

L'XML è qui sotto:

<Books> 
<Book name="name1" title="title1"/> 
<Book name="name2" title="title2"/> 
</Books> 
+0

Ti manca il tuo XML o è stato ingoiato in qualche modo. –

+0

Non rimanere bloccato su come XML * dovrebbe * apparire in app.config. Sii felice che funzioni. – Will

risposta

5

Che cosa si vuole fare è leggere su Custom Configuration Sections.

+1

E buona fortuna ai noob che hanno il coraggio di farlo! Possono essere molto confusi per un nuovo sviluppatore. – Will

+2

Vero, il modo .NET 1.x in cui hai implementato un'interfaccia e hai avuto modo di giocare con l'XML era molto più facile da capire, IMO. –

+2

Ho trovato questa serie di articoli su codeproject (http://www.codeproject.com/KB/dotnet/mysteriesofconfiguration.aspx) per essere una buona spiegazione sull'argomento. –

14

In un progetto che ho sviluppato uso qualcosa di simile per la configurazione che ho trovato. Credo che l'articolo sia stato chiamato l'ultimo gestore di sezioni di configurazione di cui avrò mai bisogno (non riesco a trovare un collegamento funzionante, forse qualcuno può collegarlo per me).

Questo metodo prende ciò che si desidera fare un ulteriore passo avanti e in realtà deserializza l'oggetto in memoria. Sto solo copiando il codice dal mio progetto, ma dovrebbe essere abbastanza semplice fare un passo indietro se tutto ciò che vuoi è l'XML.

Innanzitutto, è necessario definire una classe che gestisca le impostazioni di configurazione.

using System; 
using System.Configuration; 
using System.Xml; 
using System.Xml.Serialization; 
using System.Xml.XPath; 


namespace Ariel.config 
{ 
    class XmlSerializerSectionHandler : IConfigurationSectionHandler 
    { 

     #region IConfigurationSectionHandler Members 

     public object Create(object parent, object configContext, XmlNode section) 
     { 
      XPathNavigator nav = section.CreateNavigator(); 
      string typename = (string)nav.Evaluate("string(@type)"); 
      Type t = Type.GetType(typename); 
      XmlSerializer ser = new XmlSerializer(t); 
      return ser.Deserialize(new XmlNodeReader(section)); 
     } 

     #endregion 
    } 
} 

Ora, diciamo che si desidera caricare una sezione di configurazione ... super facile, gettato al tipo di oggetto che si aspetta di XML serializzare, e passare la sezione che si sta cercando (in questo caso SearchSettings.

try 
{ 
    config = (Eagle.Search.SearchSettings)ConfigurationSettings.GetConfig("SearchSettings"); 
} 
catch (System.Configuration.ConfigurationException ex) 
{ 
    syslog.FatalException("Loading search configuration failed, you likely have an error", ex); 
    return; 
} 

Ora, tutto ciò che serve è il file App.config. ho scelto di dividere la mia in file separati (1 file per sezione) solo per rendere la gestione della configurazione di un po 'più facile. si definisce un sezione, dargli un nome e definire il tipo (qualunque sia la classe sopra elencata) e il nome dell'assembly.

App.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <section name="SearchSettings" type="Ariel.config.XmlSerializerSectionHandler, Ariel"/> 
    </configSections> 
    <SearchSettings configSource="Config\Search.config" /> 
</configuration> 

Ora, tutto quello che resta è il file di configurazione per essere de-serializzato. Ciò che è importante qui è che il blocco corrisponde al nome della sezione, e il tuo tipo è l'oggetto a cui deve essere de-serializzato e il nome dell'Assembly.

<?xml version="1.0" encoding="utf-8" ?> 
<SearchSettings type="Eagle.Search.SearchSettings, Eagle"> 
    <NumThreads>4</NumThreads> 
</SearchSettings> 

Se si desidera solo l'XML grezzo puro, tutto cio che dovrete fare è modificare l'oggetto che gestisce la sezione di restituire l'XML o fare quello che devi fare.

+1

Sembra un collegamento stabile: http://sites.google.com/site/craigandera/craigs-stuff/clr-workings/the-last-configuration-section-handler-i-ll-ever-need. L'unico problema che vedo con il suo approccio è che se ne hai una tonnellata di tali sezioni, sarà pieno di dichiarazioni di tipo. Ma potresti aggirare questo svantaggio incollandoli insieme in una sezione e creando un tipo più grande. In quanto tale, sembra abbastanza fattibile e un hack piuttosto elegante. –

+0

Grazie! Questo è stato molto utile. – JDPeckham

+0

Phil Haack ha fatto una versione aggiornata basata sull'approccio di Craig che supporta il ricaricamento della configurazione se il file cambia. La formattazione è tutta rotta nel passaggio al suo nuovo blog, ma il collegamento è http://haacked.com/archive/2004/06/24/verylastconfigurationsectionhandler.aspx/ – piers7

0

Io uso xml personalizzato nel mio config.app. file e creare un'app.XSD da esso. Il file XSD include lo schema del file config.app. Quindi il file XSD può essere tradotto in una classe vb o in un file di classe C# utilizzando 'xsd.exe'. Ora tutto ciò che devi fare è deserializzare il file di configurazione nella classe.

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
     <section name="CustomConfig" type="Object" /> 
    </configSections> 

    <CustomConfig> 
     <ActiveEnvironment>QAS</ActiveEnvironment> 
     <Environments> 
      <Environment name ="PRD" log="Y"> 
      </Environment> 
      <Environment name ="QAS" log="N"> 
      </Environment> 
      <Environment name ="DEV" log="Y"> 
      </Environment> 
     </Environments> 
    </CustomConfig> 

</configuration> 
+2

Disporre il tuo tipo in Xml, quindi generare automaticamente una classe da esso sembra piuttosto avvincente. Come si "crea un'app.XSD da esso"? +1 quando aggiungi queste istruzioni alla tua risposta;) –

+0

Puoi creare XSD da VS. Crea un file XML di esempio, quindi sulla barra degli strumenti in VS2017, c'è un menu 'XML' con l'opzione "Crea schema". Maggiori informazioni su MSDN all'indirizzo https://msdn.microsoft.com/en-us/library/ms255829.aspx –

4

Dal IConfigurationSectionHandler è deprecato ho pensato che la pena ricordare che è ancora possibile implementare una sezione serializzato pura semplicemente sovrascrivendo ConfigurationSection.DeserializeSection e non chiamare l'implementazione di base.

Ecco un esempio molto semplice che riutilizza molto. Una semplice sezione di configurazione che carica un grafico oggetto da XAML in linea.(Naturalmente puoi implementare con XmlSerializer)

using System.Configuration; 
using System.Xaml; 
using System.Xml; 

... 

public class XamlConfigurationSection<T> : ConfigurationSection 
{ 
    public static XamlConfigurationSection<T> Get(string sectionName) 
    { 
     return (XamlConfigurationSection<T>)ConfigurationManager.GetSection(sectionName); 
    } 

    public T Content { get; set; } 

    protected override void DeserializeSection(XmlReader xmlReader) 
    { 
     xmlReader.Read(); 
     using (var xamlReader = new XamlXmlReader(xmlReader)) 
      Content = (T)XamlServices.Load(xamlReader); 
    } 
} 
+0

+1 'ConfigurationSection.DeserializeSection' è un salvataggi poiché è più semplice iterare sul nodo XML cfg pertinente invece di occuparsi di w/System.Configurazione di varie annotazioni e ancora esposizione di elementi di configurazione statici/fortemente sicuri –

Problemi correlati