Benutzer mit den meisten Antworten
config-Datei auslesen mit Hilfe einer Klasse

Frage
-
Hallo,
ich will aus einer Konfigurationsdatei (z.B. Test_ReadData.exe.config) die Einstellungen für ApplicationConfiguration (name, type, filePath) auslesen mit Hilfe einer Klasse.
Inhalt der Datei Test_ReadData.exe.config:
<configuration>
<configSections>
<section name=" ApplicationConfiguration "
type="a, b, Version=1.1.0.0, Culture=neutral, PublicKeyToken=abc" />
</configSections>
<appSettings>
</appSettings>
< ApplicationConfiguration selectedSource="File Configuration Source">
<sources>
<add name="File Configuration Source"
type="a, b, Version=1.1.0.0, Culture=neutral, PublicKeyToken=abc"
filePath=".\test.config" />
</sources>
</ ApplicationConfiguration >
</configuration>
public class ApplicationConfiguration : ConfigurationSection
{
public ApplicationConfiguration() {}
[ConfigurationProperty("name")]
public string Name
{
get { return (string) this["name"]; }
set { this["name"] = value;}
}
[ConfigurationProperty("type")]
public string Type
{
get { return (string)this["type"]; }
set { this["type"] = value; }
}
[ConfigurationProperty("filePath")]
public string FilePath
{
get { return (string)this["filePath"]; }
set { this["filePath"] = value; }
}
}
Und in einer anderen Klasse die Konfiguration auslesen:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
Console.WriteLine("config-file: {0} ", config.FilePath);
ApplicationConfiguration settings = ConfigurationManager.GetSection("ApplicationConfiguration") as ApplicationConfiguration;
Console.WriteLine(settings.Name); //<<<< Error
settings ist immer null ("Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.“). Hat jemand eine Idee warum? Liegt es an der xml-Struktur?
Alexander
Antworten
-
Hallo Alexander,
hier ein grober Ansatz:using System; using System.Configuration; using System.Windows.Forms; namespace WinConfigSection { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // Hiermit den Inhalt für die "type"-Eigenschaft in der app.config bestimmen: string test = typeof(ApplicationConfiguration).AssemblyQualifiedName; Configuration config = ConfigurationManager. OpenExeConfiguration(ConfigurationUserLevel.None); Console.WriteLine("config-file: {0} ", config.FilePath); var section = ConfigurationManager.GetSection("ApplicationConfiguration"); ApplicationConfiguration settings = section as ApplicationConfiguration; MessageBox.Show("SelectedSource: " + settings.SelectedSource); } public class ApplicationConfiguration : ConfigurationSection { public ApplicationConfiguration() { } [ConfigurationProperty("name")] public string Name { get { return (string)this["name"]; } set { this["name"] = value; } } [ConfigurationProperty("type")] public string Type { get { return (string)this["type"]; } set { this["type"] = value; } } [ConfigurationProperty("filePath")] public string FilePath { get { return (string)this["filePath"]; } set { this["filePath"] = value; } } [ConfigurationProperty("selectedSource")] public string SelectedSource { get { return (string)this["selectedSource"]; } set { this["selectedSource"] = value; } } [ConfigurationProperty("sources")] public SourcesElement Sources { get { return (SourcesElement)this["sources"]; } set { this["sources"] = value; } } } public class SourcesElement : ConfigurationElementCollection { [ConfigurationProperty("name", DefaultValue = "DeinName")] public String Name { get{return (string)this["name"];} set{this["name"] = value;} } [ConfigurationProperty("filePath")] public string FilePath { get { return (string)this["filePath"]; } set { this["filePath"] = value; } } protected override ConfigurationElement CreateNewElement() { return new SourcesElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((SourcesElement)element).Name; } } } }
______________________
app.config:<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="ApplicationConfiguration"
type="WinConfigSection.Form1+ApplicationConfiguration,
WinConfigSection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<appSettings>
</appSettings>
<ApplicationConfiguration
selectedSource="File Configuration Source">
<sources>
<add
name="File Configuration Source"
filePath=".\test.config" />
</sources>
</ApplicationConfiguration>
</configuration>______________________
[ConfigurationElementCollection-Klasse (System.Configuration)]
http://msdn.microsoft.com/de-de/library/system.configuration.configurationelementcollection.aspx
[ConfigurationElement-Klasse (System.Configuration)]
http://msdn.microsoft.com/de-de/library/system.configuration.configurationelement.aspx
ciao Frank- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 15. September 2010 14:36
-
Hallo Alexander,
Du hast Recht, da waren noch ein paar Klopfer in meinem Code, ich hatte relativ schnell als Ansatz gepostet, weil ich auch dachte, der Rest wäre einfach. Ich habe Dir mal hier für mein Beispiel den verbesserten Code aufgeführt. App.config bleibt natürlich wie sie ist, Code aber so:private void Form1_Load(object sender, EventArgs e) { string test = typeof(ApplicationConfiguration).AssemblyQualifiedName; Configuration config = ConfigurationManager. OpenExeConfiguration(ConfigurationUserLevel.None); Console.WriteLine("config-file: {0} ", config.FilePath); var section = ConfigurationManager.GetSection("ApplicationConfiguration"); ApplicationConfiguration settings = section as ApplicationConfiguration; MessageBox.Show("SelectedSource: " + settings.SelectedSource); foreach (SourcesElement c in settings.Sources) MessageBox.Show("FilePath=" + c.FilePath + "\nType=" + c.Type + "\nName=" + c.Name); } public class ApplicationConfiguration : ConfigurationSection { public ApplicationConfiguration() { } [ConfigurationProperty("selectedSource")] public string SelectedSource { get { return (string)this["selectedSource"]; } set { this["selectedSource"] = value; } } [ConfigurationProperty("sources")] public SourcesElements Sources { get { return (SourcesElements)this["sources"]; } set { this["sources"] = value; } } } public class SourcesElements : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new SourcesElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((SourcesElement)element).Name; } } public sealed class SourcesElement : ConfigurationElement { [ConfigurationProperty("name")] public string Name { get { return (string)this["name"]; } set { this["name"] = value; } } [ConfigurationProperty("type")] public string Type { get { return (string)this["type"]; } set { this["type"] = value; } } [ConfigurationProperty("filePath")] public string FilePath { get { return (string)this["filePath"]; } set { this["filePath"] = value; } } }
_________________________
Weitere Infos und Beispiele auch hier[Creating a Custom Configuration Section in C# - CodeProject]
http://www.codeproject.com/KB/cs/CustomConfigurationSectio.aspxBTW: vielleicht etwas komplex, aber in folgendem Download gibt es unter dem Verzeichnis
"...PrismLibrary\Desktop\Prism\Modularity\" auch eine "ConfigurationStore.Desktop.cs" und "ConfigurationModuleCatalog.Desktop.cs" Klasse (u. weitere) , die soetwas macht. [patterns & practices: Prism ->Drop 7]. Nur, weil das hier oft sehr sauber implementiert ist. Ist aber evtl. doch zu komplex, weil dort auch über loose Kopplung gearbeitet wird.
ciao Frank- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 15. September 2010 14:36
-
Hallo Alexander,
ich habe mal ein älteres Beispiel ausgegraben und auf Deine Angaben angepasst:
using System; using System.Configuration; namespace ElmarBoye.Samples.Code { public sealed class ApplicationConfigurationSection : System.Configuration.ConfigurationSection { public ApplicationConfigurationSection() { } [ConfigurationProperty("selectedSource", IsRequired = true)] public string SelectedSource { get { return (string)this["selectedSource"]; } set { this["selectedSource"] = value; } } [ConfigurationProperty("sources", IsDefaultCollection = true)] public ApplicationConfigurationElementCollection Sources { get { return (ApplicationConfigurationElementCollection)this["sources"]; } set { this["sources"] = value; } } } public sealed class ApplicationConfigurationElementCollection : ConfigurationElementCollection { // Ignorieren Groß-/Kleinschreibung internal ApplicationConfigurationElementCollection() : base(StringComparer.OrdinalIgnoreCase) { } protected override ConfigurationElement CreateNewElement() { return new ApplicationConfigurationElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((ApplicationConfigurationElement)element).Name; } protected override string ElementName { get { return "sources"; } } } public sealed class ApplicationConfigurationElement : ConfigurationElement { [ConfigurationProperty("name", IsKey = true, IsRequired = true)] public string Name { get { return (string)base["name"]; } set { base["name"] = value; } } [ConfigurationProperty("filePath", IsRequired = true)] public string FilePath { get { return (string)base["filePath"]; } set { base["filePath"] = value; } } public override string ToString() { string output = "ApplicationConfigurationElement :\n"; output += string.Format("\tName = {0}\n", this.Name); output += string.Format("\tFilePath = {0}\n", this.FilePath); return output; } } }
dazu der Testcode:
var section = ConfigurationManager.GetSection("ApplicationConfiguration"); var settings = section as ApplicationConfigurationSection; Console.WriteLine("Selected Source: {0}", settings.SelectedSource); foreach (ApplicationConfigurationElement element in settings.Sources) { Console.WriteLine("Source: '{0}' = '{1}'", element.Name, element.FilePath); }
der vom Zugriff auf die aktuelle Konfigurationsdatei ausgeht.
Dazu die verwendete App.Config (relevante Ausschnitte):
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!--Assembly entsprechend anpassen--> <section name="ApplicationConfiguration" type="ElmarBoye.Samples.Code.ApplicationConfigurationSection, CS00"/> </configSections> <ApplicationConfiguration selectedSource="File Configuration Source"> <sources> <add name="File Configuration Source" filePath=".\test.config" /> <add name="Alternate Source" filePath=".\alternate.config" /> </sources> </ApplicationConfiguration> </configuration>
hier mit zwei Elementen, um die Auflistung zu testen.
Gruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 15. September 2010 14:36
Alle Antworten
-
On Tue, 07 Sep 2010 15:17:53 +0200, <AlexanderRi> wrote:> Hallo,>> ich will aus einer Konfigurationsdatei (z.B. Test_ReadData.exe.config)> die> Einstellungen für ApplicationConfiguration (name, type, filePath)> auslesen mit> Hilfe einer Klasse.>> Inhalt der Datei Test_ReadData.exe.config:>> <configuration>>> <configSections>>> <section name=" ApplicationConfiguration ">> type="a, b, Version=1.1.0.0, Culture=neutral, PublicKeyToken=a bc" />>> </configSections>>> <appSettings>>> </appSettings>>> < ApplicationConfiguration selectedSource="File Configuration Source ">>> <sources>>> <add name="File Configuration Source">> type="a, b, Version=1.1.0.0, Culture=neutral, PublicKeyToken=a bc">> filePath=".\test.config" />>> </sources>>> </ ApplicationConfiguration >>> </configuration>>> public class ApplicationConfiguration : ConfigurationSection>> {>> public ApplicationConfiguration() {}>> [ConfigurationProperty("name")]>> public string Name>> {>> get { return (string) this["name"]; }>> set { this["name"] = value;}>> }>> [ConfigurationProperty("type")]>> public string Type>> {>> get { return (string)this["type"]; }>> set { this["type"] = value; }>> }>> [ConfigurationProperty("filePath")]>> public string FilePath>> {>> get { return (string)this["filePath"]; }>> set { this["filePath"] = value; }>> }>> }>> Und in einer anderen Klasse die Konfiguration auslesen:>> Configuration config => ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None) ;>> Console.WriteLine("config-file: {0} ", config.FilePath);>> ApplicationConfiguration settings => ConfigurationManager.GetSection("ApplicationConfiguration")> as ApplicationConfiguration;>> Console.WriteLine(settings.Name); //<<<< Error>> settings ist immer null ("Der Objektverweis wurde nicht auf eine> Objektinstanz> festgelegt.�??). Hat jemand eine Idee warum? Liegt es an der xml -Struktur?>> Alexander>Hallo Alexander,falls Du den Inhalt der config Datei oben reinkopiert hast ( nichtabgetippt ), dann solltest Du bei GetSection() auch die Spaces vor undnach ApplicationConfiguration mit angeben.
Hannes
If you have got questions about this, just ask.
Mark the thread as answered if the answer helps you. This helps others who have the same problem !
C# to VB.NET: http://www.developerfusion.com/tools/convert/csharp-to-vb/ -
Hallo Alexander,
hier ein grober Ansatz:using System; using System.Configuration; using System.Windows.Forms; namespace WinConfigSection { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // Hiermit den Inhalt für die "type"-Eigenschaft in der app.config bestimmen: string test = typeof(ApplicationConfiguration).AssemblyQualifiedName; Configuration config = ConfigurationManager. OpenExeConfiguration(ConfigurationUserLevel.None); Console.WriteLine("config-file: {0} ", config.FilePath); var section = ConfigurationManager.GetSection("ApplicationConfiguration"); ApplicationConfiguration settings = section as ApplicationConfiguration; MessageBox.Show("SelectedSource: " + settings.SelectedSource); } public class ApplicationConfiguration : ConfigurationSection { public ApplicationConfiguration() { } [ConfigurationProperty("name")] public string Name { get { return (string)this["name"]; } set { this["name"] = value; } } [ConfigurationProperty("type")] public string Type { get { return (string)this["type"]; } set { this["type"] = value; } } [ConfigurationProperty("filePath")] public string FilePath { get { return (string)this["filePath"]; } set { this["filePath"] = value; } } [ConfigurationProperty("selectedSource")] public string SelectedSource { get { return (string)this["selectedSource"]; } set { this["selectedSource"] = value; } } [ConfigurationProperty("sources")] public SourcesElement Sources { get { return (SourcesElement)this["sources"]; } set { this["sources"] = value; } } } public class SourcesElement : ConfigurationElementCollection { [ConfigurationProperty("name", DefaultValue = "DeinName")] public String Name { get{return (string)this["name"];} set{this["name"] = value;} } [ConfigurationProperty("filePath")] public string FilePath { get { return (string)this["filePath"]; } set { this["filePath"] = value; } } protected override ConfigurationElement CreateNewElement() { return new SourcesElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((SourcesElement)element).Name; } } } }
______________________
app.config:<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="ApplicationConfiguration"
type="WinConfigSection.Form1+ApplicationConfiguration,
WinConfigSection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<appSettings>
</appSettings>
<ApplicationConfiguration
selectedSource="File Configuration Source">
<sources>
<add
name="File Configuration Source"
filePath=".\test.config" />
</sources>
</ApplicationConfiguration>
</configuration>______________________
[ConfigurationElementCollection-Klasse (System.Configuration)]
http://msdn.microsoft.com/de-de/library/system.configuration.configurationelementcollection.aspx
[ConfigurationElement-Klasse (System.Configuration)]
http://msdn.microsoft.com/de-de/library/system.configuration.configurationelement.aspx
ciao Frank- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 15. September 2010 14:36
-
Hallo Frank,
vielen Dank für Deine Hilfe. Ich habe das Beispiel von Dir mit dem gleichen Aufbau "nachgebaut".
Die MessageBox wird mit "SelectedSource: File Configuration Source" angezeigt. Jedoch erhalte ich mit
Console.WriteLine(">>>>>> Ergebnis: {0}, {1}, {2}", settings.Name, settings.Type, settings.FilePath);
keine Werte. Das Objekt settings existiert, jedoch besitzen die drei Eigenschaften keine Werte.
Ich kann mir den Fehler nicht erklären. Wo kann die Ursache liegen?
Alexander
-
Hallo,
wie schon beschrieben, will ich die untenstehende Konfigurationsdatei auslesen. Ich habe jetzt noch ein Problem.
Mit dem Code
var section = ConfigurationManager.GetSection("ApplicationConfiguration");
erhalte ich für section immer null.
Ändere ich in der config-Datei die Zeile
< ApplicationConfiguration selectedSource="File Configuration Source">
in
< ApplicationConfiguration selectedSource>
dann ist section nicht null,d.h. ich kann die Werte von <sources> auslesen.
Was muss ich an
var section = ConfigurationManager.GetSection("ApplicationConfiguration");
ändern?
Alexander
Inhalt der Datei Test_ReadData.exe.config:
<configuration>
<configSections>
<section name=" ApplicationConfiguration "
type="a, b, Version=1.1.0.0, Culture=neutral, PublicKeyToken=abc" />
</configSections>
<appSettings>
</appSettings>
< ApplicationConfiguration selectedSource="File Configuration Source">
<sources>
<add name="File Configuration Source"
type="a, b, Version=1.1.0.0, Culture=neutral, PublicKeyToken=abc"
filePath=".\test.config" />
</sources>
</ ApplicationConfiguration >
</configuration>
-
Hallo Alexander,
Du hast Recht, da waren noch ein paar Klopfer in meinem Code, ich hatte relativ schnell als Ansatz gepostet, weil ich auch dachte, der Rest wäre einfach. Ich habe Dir mal hier für mein Beispiel den verbesserten Code aufgeführt. App.config bleibt natürlich wie sie ist, Code aber so:private void Form1_Load(object sender, EventArgs e) { string test = typeof(ApplicationConfiguration).AssemblyQualifiedName; Configuration config = ConfigurationManager. OpenExeConfiguration(ConfigurationUserLevel.None); Console.WriteLine("config-file: {0} ", config.FilePath); var section = ConfigurationManager.GetSection("ApplicationConfiguration"); ApplicationConfiguration settings = section as ApplicationConfiguration; MessageBox.Show("SelectedSource: " + settings.SelectedSource); foreach (SourcesElement c in settings.Sources) MessageBox.Show("FilePath=" + c.FilePath + "\nType=" + c.Type + "\nName=" + c.Name); } public class ApplicationConfiguration : ConfigurationSection { public ApplicationConfiguration() { } [ConfigurationProperty("selectedSource")] public string SelectedSource { get { return (string)this["selectedSource"]; } set { this["selectedSource"] = value; } } [ConfigurationProperty("sources")] public SourcesElements Sources { get { return (SourcesElements)this["sources"]; } set { this["sources"] = value; } } } public class SourcesElements : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new SourcesElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((SourcesElement)element).Name; } } public sealed class SourcesElement : ConfigurationElement { [ConfigurationProperty("name")] public string Name { get { return (string)this["name"]; } set { this["name"] = value; } } [ConfigurationProperty("type")] public string Type { get { return (string)this["type"]; } set { this["type"] = value; } } [ConfigurationProperty("filePath")] public string FilePath { get { return (string)this["filePath"]; } set { this["filePath"] = value; } } }
_________________________
Weitere Infos und Beispiele auch hier[Creating a Custom Configuration Section in C# - CodeProject]
http://www.codeproject.com/KB/cs/CustomConfigurationSectio.aspxBTW: vielleicht etwas komplex, aber in folgendem Download gibt es unter dem Verzeichnis
"...PrismLibrary\Desktop\Prism\Modularity\" auch eine "ConfigurationStore.Desktop.cs" und "ConfigurationModuleCatalog.Desktop.cs" Klasse (u. weitere) , die soetwas macht. [patterns & practices: Prism ->Drop 7]. Nur, weil das hier oft sehr sauber implementiert ist. Ist aber evtl. doch zu komplex, weil dort auch über loose Kopplung gearbeitet wird.
ciao Frank- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 15. September 2010 14:36
-
Hallo Alexander,
ich habe mal ein älteres Beispiel ausgegraben und auf Deine Angaben angepasst:
using System; using System.Configuration; namespace ElmarBoye.Samples.Code { public sealed class ApplicationConfigurationSection : System.Configuration.ConfigurationSection { public ApplicationConfigurationSection() { } [ConfigurationProperty("selectedSource", IsRequired = true)] public string SelectedSource { get { return (string)this["selectedSource"]; } set { this["selectedSource"] = value; } } [ConfigurationProperty("sources", IsDefaultCollection = true)] public ApplicationConfigurationElementCollection Sources { get { return (ApplicationConfigurationElementCollection)this["sources"]; } set { this["sources"] = value; } } } public sealed class ApplicationConfigurationElementCollection : ConfigurationElementCollection { // Ignorieren Groß-/Kleinschreibung internal ApplicationConfigurationElementCollection() : base(StringComparer.OrdinalIgnoreCase) { } protected override ConfigurationElement CreateNewElement() { return new ApplicationConfigurationElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((ApplicationConfigurationElement)element).Name; } protected override string ElementName { get { return "sources"; } } } public sealed class ApplicationConfigurationElement : ConfigurationElement { [ConfigurationProperty("name", IsKey = true, IsRequired = true)] public string Name { get { return (string)base["name"]; } set { base["name"] = value; } } [ConfigurationProperty("filePath", IsRequired = true)] public string FilePath { get { return (string)base["filePath"]; } set { base["filePath"] = value; } } public override string ToString() { string output = "ApplicationConfigurationElement :\n"; output += string.Format("\tName = {0}\n", this.Name); output += string.Format("\tFilePath = {0}\n", this.FilePath); return output; } } }
dazu der Testcode:
var section = ConfigurationManager.GetSection("ApplicationConfiguration"); var settings = section as ApplicationConfigurationSection; Console.WriteLine("Selected Source: {0}", settings.SelectedSource); foreach (ApplicationConfigurationElement element in settings.Sources) { Console.WriteLine("Source: '{0}' = '{1}'", element.Name, element.FilePath); }
der vom Zugriff auf die aktuelle Konfigurationsdatei ausgeht.
Dazu die verwendete App.Config (relevante Ausschnitte):
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!--Assembly entsprechend anpassen--> <section name="ApplicationConfiguration" type="ElmarBoye.Samples.Code.ApplicationConfigurationSection, CS00"/> </configSections> <ApplicationConfiguration selectedSource="File Configuration Source"> <sources> <add name="File Configuration Source" filePath=".\test.config" /> <add name="Alternate Source" filePath=".\alternate.config" /> </sources> </ApplicationConfiguration> </configuration>
hier mit zwei Elementen, um die Auflistung zu testen.
Gruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 15. September 2010 14:36