C# and App.config

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

All,

I have a app.config which contains repeating tags as shown below:

<filelist>
<file>
<filetype>xxx</filetype>
<hex>yyyy</hex>
</file>

<file>
<filetype>aaa</filetype>
<hex>bbb</hex>
</file>
</filelist>

Can anyone suggest a way to read these values out and say load them into a
arraylist?

Thanks
Msuk
 
You say thay are in the app.config? How are they structured in the
app.config? Are they in the <appSettings> tag or some specialized tag.

Or is this a config file that has no relation to the app.config file used by
the Configuration namespace?
 
I have a app.config which contains repeating tags as shown below:
<filelist>
<file>
<filetype>xxx</filetype>
<hex>yyyy</hex>
</file>

<file>
<filetype>aaa</filetype>
<hex>bbb</hex>
</file>
</filelist>

Can anyone suggest a way to read these values out and say load them into a
arraylist?

You'd have to write your own custom config section handler - and it's
really not that frightening as it may sound!

Basically, you need a class which implements the
"IConfigurationSectionHandler " interface. This is a really simple
interface, which contains only a single method - "Create". That method
takes a XmlNode from your config files, and passes it to your class -
you then need to parse that and return some arbitrary object (e.g. an
ArrayList).

So your section handler would look something like:

public class MyFileListHandler : IConfigurationSectionHandler
{
public object Create(object parent, object ConfigContext, XmlNode
section)
{
ArrayList alsResult = new ArrayList();

// you get the node containing the <filelist>.....</filelist>
// so iterate over all <file> tags contained in it
XmlNodeList oListOfFiles = section.SelectNodes("//file");

// for each <file> node, grab its <filetype> and <hex>
// child nodes and store into your custom object
foreach(XmlNode oSingleFileNode in oListOfFiles)
{
// grab the child nodes
XmlNode oFileType =
oSingleFileNode.SelectSingleNode("//filetype");
string sFileType = oFileType.Value;

XmlNode oHex = oSingleFileNode.SelectSingleNode("//hex");
string sHex = oHex.Value;

alsResult.Add(new FileTypeHex(sFileType, sHex));
}

return alsResult;
}
}

And lastly, you need to define this custom section in your app.config
file, so that the .NET configuration system will know about it:

<configuration>
<configSections>
<section name="filelist"
type="YourAssembly.MyFileListHandler" />
</configSections>

<filelist>
<file>
<filetype>xxx</filetype>
<hex>yyyy</hex>
</file>
<file>
<filetype>aaa</filetype>
<hex>bbb</hex>
</file>
</filelist>
</configuration>

That should work and it's really quite easy, once you've done it and
you've gotten the hang of it !

Marc

================================================================
Marc Scheuner May The Source Be With You!
Berne, Switzerland m.scheuner -at- inova.ch
 
Hi,

thanks for your response, I am still a bit confused and was wondering if you
could help me.

public object Create(object parent, object ConfigContext, XmlNode
section)

I have created the function below and wanted to know what I need to pass to
the 'Create' i.e.

what is the 'parent', 'ConfigContext' and the 'XmlNode'.

Also how do I find the 'FileTypeHex' as my project does not build

alsResult.Add(new FileTypeHex(sFileType, sHex));

Thanks
 
public object Create(object parent, object ConfigContext, XmlNode
section)

I have created the function below and wanted to know what I need to pass to
the 'Create' i.e.

what is the 'parent', 'ConfigContext' and the 'XmlNode'.

Those are just additional parameters that might get passed into the
Create function - not sure if they're really even being populated at
this time. But as another poster already mentioned - you never have to
call Create yourself! You just write the code, and make it available
to the .NET runtime - the runtime will then call your code when
needed.
Also how do I find the 'FileTypeHex' as my project does not build
alsResult.Add(new FileTypeHex(sFileType, sHex));

I didn't include it since it seemed like a totally simple thing to do
- it would be a small class you have to write yourself, to hold the
"filetyp" and the "hex" values. Something like:

public class FileTypeHex
{
private string m_sFileType = string.Empty;
private string m_sHex = string.Empty;

public FileTypeHex(string aFileType, string aHex)
{
m_sFileType = aFileType;
m_sHex = aHex;
}

public string FileType
{
get { return m_sFileType; }
}

public string Hex
{
get { return m_sHex; }
}
}


Marc
================================================================
Marc Scheuner May The Source Be With You!
Berne, Switzerland m.scheuner -at- inova.ch
 
public object Create(object parent, object ConfigContext, XmlNode
section)

I have created the function below and wanted to know what I need to pass
to
the 'Create' i.e.
what is the 'parent', 'ConfigContext' and the 'XmlNode'.

You don't. You call ConfigurationSettings.GetConfig() passing the name of
the section according to the values in <configSections> for Marc's code this
will be "filelist" (Note that the type attribute of <section> should be a
fully qualified name, so it should include the full assembly name too, see
machine.config for examples.) The system then calls Create on your behalf.
The second parameter is only used by ASP.NET. It *may* call this method
twice, if machine.config has the section then Create will be called with
null for the first parameter, and the section in the last parameter. If the
app config has the section too, then Create is called again with the object
returned from the first call to Create in the first parameter and the
section from the app config in the last parameter. It is up to you what you
do with a non-null parent parameter, but usually the app data overwrites the
values from machine.config.

Richard
 
Hi,

Thanks for your response, after some experimenting I finally got it working.
The next problem I have is that if I create a class that has the GetConfig()
method and implements the IConfigurationSectionHandler and complie in to a
dll, then add this as a reference to say my aspx form, when I try to get any
values back I repeatly get 'Object reference not set to an instance of an
object'

The GetConfig() is a static method called as follows from my aspx form

string exe = ConfigurationSample2.SampleConfiguration.GetConfig.ExeName -
fails with 'Object reference not set to an instance of an object' what am I
doing wrong.

Thanks
Msuk
 
msuk said:
The GetConfig() is a static method called as follows from my aspx form

string exe =
ConfigurationSample2.SampleConfiguration.GetConfig.ExeName - fails
with 'Object reference not set to an instance of an object' what am I
doing wrong.

Huh?

You should do this:

string exe =
System.Configuration.ConfigurationSettings.GetConfig("filelist");

Richard
 
All,

I am still getting the following error - 'Object reference not set to an
instance of an object' below is the code I am using.

I have the following App.Config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="MyCompany">
<section name="Filelist"
type="ConfigurationSample.SampleConfigurationHandler,MyAssembleyName" />
</sectionGroup>
</configSections>
<MyCompany>
<Filelist location="C:\Program Files\zzz\xxx.EXE">
<Files>
<add type=".jpg" hex="FFD8FFE0" />
<add type=".gif" hex="47494638" />
<add type=".bmp" hex="424D" />
</Files>
</Filelist>
</MyCompany>
</configuration>

I have one assembley (MyAssembleyName.dll) that contains the following code
to get the section I need:

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

namespace ConfigurationSample {
public class SampleConfiguration
{
#region fields and properties

private string m_Exe;

public string ExeName
{
get { return m_Exe; }
set { m_Exe = value; }
}


#endregion


#region Constructors
public SampleConfiguration() {}
#endregion


public static SampleConfiguration GetConfig{
get {return
(SampleConfiguration)ConfigurationSettings.GetConfig("MyCompany/Filelist");}
}

internal void LoadValues(XmlNode node) {
XmlAttributeCollection attributeCollection = node.Attributes;
m_Exe = attributeCollection["location"].Value;

}

}

public class SampleConfigurationHandler : IConfigurationSectionHandler
{
public object Create(object parent, object context, XmlNode node)
{
SampleConfiguration config = new SampleConfiguration();
config.LoadValues(node);
return config;
}
}
}

In a separate solutuion I have a webform that has a reference to
MyAssembleyName.dll and I call the following method on the page load:

using ...
using ConfigurationSample;

try
{
string exeName = SampleConfiguration.GetConfig.ExeName
}
catch (Exception ex)
{
throw ex;
}

An exception is thrown saying - 'Object reference not set to an instance of
an object' what am I doing wrong?

Thanks
Msuk
 
try
{
string exeName = SampleConfiguration.GetConfig.ExeName
}
catch (Exception ex)
{
throw ex;
}
An exception is thrown saying - 'Object reference not set to an instance of
an object' what am I doing wrong?

You're not instantiating a "SampleConfiguration" object - that's what
it is.

What you need to do in this scenario is *NOT* to use
SampleConfiguraiton and its handler DIRECTLY - leave that up to the
..NET framework !!

Just call:

object oMyConfig = ConfigurationSettings.GetConfig("Filelist");

This will return that object to you, the one you're creating in the
configuraiton handler.

Once you have that object, you can typecast it to whatever you need.

Marc

================================================================
Marc Scheuner May The Source Be With You!
Berne, Switzerland m.scheuner -at- inova.ch
 
Hi,

If I use object oMyConfig = ConfigurationSettings.GetConfig("Filelist");
from my Webform I will need to add the namespace System.Configuration so
wont the framework look in the web.config file which is not where I want to
look. I want to look at the app.config associated with MyAssembley.dll?

Thanks
Msuk
 
Hi,

After some futher investigation I have discovered that as MyAssembley.dll
has been added as a reference to my separate solution containing the
Webform1.aspx it seem to look for the sections in the web.config as if I copy
the entries from the App.config for the MyAssembley.dll it works.

This is not what I am after all I want to do is have a app.config associated
with MyAssembley.dll and add MyAssembley.dll to my web project and get values
from the app.config. Is this possible?

Thanks
MSuk

I have some sample code if anyone can help me please :-(
 
If I use object oMyConfig = ConfigurationSettings.GetConfig("Filelist");
from my Webform I will need to add the namespace System.Configuration so
wont the framework look in the web.config file which is not where I want to
look. I want to look at the app.config associated with MyAssembley.dll?

Your assembly will *NOT* have a .config file of its own - at least not
with the standard .NET configuration packages - it's just not the way
MS designed this, sorry.

You would need to use a totally different set of components to handle
this case - check on e.g. www.codeproject.com for alternate
Configuration components - there are plenty.

Marc
================================================================
Marc Scheuner May The Source Be With You!
Berne, Switzerland m.scheuner -at- inova.ch
 
Back
Top