I've been following this tutorial on msdn which loads a custom configSection. http://msdn.microsoft.com/en-us/library/system.configuration.configurationcollectionattribute.aspx I'm doing this in asp.net and I keep getting an error on
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None) as Configuration;
so i removed that and just used
UrlsSection myUrlsSection =
ConfigurationManager.GetSection("MyUrls") as UrlsSection;
Could someone copy and past the code from msdn and make a project in asp.net and test the code and see if they get same error or see if myUrlsSection = null and if you don't get a problem could you share what you did to make it work
This is what I tried and it works nice.
UrlsSection myUrlsSection =
ConfigurationManager.GetSection("MyUrls") as UrlsSection;
My UrlsSection class
namespace MyProject
{
public class UrlsSection : ConfigurationSection
{
}
}
And my config entry.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="MyUrls" type="MyProject.UrlsSection, MyProject" />
</configSections>
<MyUrls />
</configuration>
Related
I'm new to C# and am still in the process of figuring out the best practices for certain things.
I want to know where I could store settings such as paths (eg. For file uploads) and other assorted variables so that they can be accessed anywhere in the project.
Should I just create a class with static variables or is there a better approach to storing these settings?
You'd better save this in the web.config since this can be changed after compilation.
The appSettings element is reserved for this kind of functionality. You can even split this part off in a different file so it is totally clear this in your specific config.
Example web.config only:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="DocumentDirectory" value="~/Documents" />
</appSettings>
</configuration>
Or:
web.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings file="appSettings.xml" />
</configuration>
And a separate appSettings.xml:
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<add key="DocumentDirectory" value="~/Documents" />
</appSettings>
You can read those settings like this:
using System.Configuration;
using System.Web.Configuration;
Configuration config = WebConfigurationManager.OpenWebConfiguration(null);
if (config.AppSettings.Settings.Count > 0)
{
KeyValueConfigurationElement customSetting = config.AppSettings.Settings["DocumentDirectory"];
if (customSetting != null)
{
string directory = customSetting.Value;
}
}
I have a Configuration-File that I read with the ConfigurationManager. There are some Sections that I defined by myself.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="applicationWideSettingsSection" type="MyTestApp.ApplicationSettings.ApplicationWideSettingsSection, MyTestAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<applicationWideSettingsSection>
<pathToSomeFile value="C:\Users\..." />
</applicationWideSettingsSection>
</configuration>
There are new requirements: now I have to store another value in the applicationWideSettingsSection like this:
<applicationWideSettingsSection>
<pathToSomeFile value="C:\Users\..." />
<pathToSomeOtherFile value="C:\Programs\..." />
</applicationWideSettingsSection>
So I change my definition of the applicationWideSettingsSection. If I now run the application with an old config-File it throws an exception on this line:
var configSection = _config.GetSection("applicationWideSettingsSection");
because there is only the pathToSomeFile-Setting and the other one is missing.
Is there a way to manually add another (default value) to this section?
How would you deal with this??
Thanks in advance, Joerg
Because I didn't want to change my design away from my custom Setting-Types I found a different way:
I set the IsRequired to false so no exception is thrown when the setting is missing. If it's missing I set it to some value from code.
In a different approach I wanted to override some of the Configuration-Section methods but did not get it to work...
now I have to store another value in the applicationWideSettingsSection
Instead of your custom type ApplicationWideSettingsSection you can use a key-value pairs, so
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="applicationWideSettingsSection"
type="System.Configuration.NameValueSectionHandler" />
</configSections>
<applicationWideSettingsSection>
<pathToSomeFile value="C:\Users\..." />
</applicationWideSettingsSection>
</configuration>
This will store 1 or many parameters and allow you to enumerate on the inner parameters. You can also try DictionarySectionHandler. I found sample code in this post.
In the root folder of my ASP.NET MVC 5 I have two config files. one is the default web.config file and the second one is department.config.
The content of the department.config file is:
<department>
<add key="dept1" value="xyz.uvw.rst" />
<add key="dept2" value="abc.def.ghi" />
<department>
How to read the department.config file ?
I want to get a collection of values under <department> in this config file.
Edit: Web.config has <department configSource="reports.config" />
so, how to read the configSource file in asp.net mvc ?
Edit:
<configuration>
<configSections>
<section name="departments"
type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
restartOnExternalChanges="false"
requirePermission="false" />
In your web.config, you can specify other files that the built-in ConfigurationManager can easily access. For example, we decided that we wanted to separate connection strings and application setting into separate files. You can do this by putting this in your web.config:
<appSettings configSource="appsettings.config" />
Then you can access these values in the 'regular' way
ConfigurationManager.AppSettings["KeyHere"]
Same thing with connection strings...
Why not use the appSettings section in your web.config? These are easy to read using ConfigurationManager object.
In your web.config, find the appSettings section:
<appSettings>
<add key="dept1" value="xyz.uvw.rst"/>
Then in your class where you want to read it, import the correct namespace:
using System.Configuration;
And then read the value easily, like so:
var dept1 = ConfigurationManager.AppSettings.Get("dept1");
If you have to have it in a separate config, you might consider creating a class for it, I'll post up an example of that shortly.
edit1: here is a quick example of how to do your own custom config
first, define the config class:
using System;
using System.Configuration;
namespace WebApplication2
{
public class MyConfig : ConfigurationSection
{
private static readonly MyConfig ConfigSection = ConfigurationManager.GetSection("MyConfig") as MyConfig;
public static MyConfig Settings
{
get
{
return ConfigSection;
}
}
[ConfigurationProperty("Dept1", IsRequired = true)]
public string Dept1
{
get
{
return (string)this["Dept1"];
}
set
{
this["Dept1"] = value;
}
}
[ConfigurationProperty("Dept2", IsRequired = true, DefaultValue = "abc.def.ghi")]
public string Dept2
{
get
{
return (string)this["Dept2"];
}
set
{
this["Dept2"] = value;
}
}
// added as example of different types
[ConfigurationProperty("CheckDate", IsRequired = false, DefaultValue = "7/3/2014 1:00:00 PM")]
public DateTime CheckDate
{
get
{
return (DateTime)this["CheckDate"];
}
set
{
this["CheckDate"] = value;
}
}
}
}
Then, set it up in your web.config file:
<configuration>
<configSections>
<section name="MyConfig" type="WebApplication2.MyConfig, WebApplication2" />
</configSections>
<MyConfig Dept1="xyz.uvw.rst" Dept2="abc.def.ghi" />
...
</configuration>
And then you can call it very easily, along with strong-typing and support for many types:
var dept1 = MyConfig.Settings.Dept1;
var dept2 = MyConfig.Settings.Dept2;
// strongly-typed
DateTime chkDate = MyConfig.Settings.CheckDate;
That's how I would do it. Use the built-in stuff and create a class for it. Easy to do config transforms with, easy to read, and easy to use.
This is an old question but in the event someone needs to know... First geekzsters answer lays out how to write a config class. Then you specify a custom Config Section and give it a configSource in a separate file.
<configuration>
<configSections>
<section name="myCustomSection" type="MyNamespace.MyCustomType" requirePermission="false" />
</configSections>
</configuration>
<myCustomSection configSource="myConfigDir\myFile.config" />
Then in your custom config file you write a normal xml config
<?xml version="1.0" encoding="utf-8"?>
<myCustomSection>
<myCustomType>
<add name="pro1" value="abc" />
<add name="prop2" value="cde" />
<add name="prop3" value="efg" />
</myCustomType>
</myCustomSection>
The simplest way to read configuration File other then Web config is to define file you want to read as follows:
webConfig
<appSettings file="TestFile.config">
<add key="webpages:Version" value="3.0.0.0"/>
<add key="webpages:Enabled" value="false"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
TestFile.Config
<appSettings>
<add key="test" value="testData"/>
</appSettings>
Above we define the file we want to read configuration from in Webconfig. thus using ConfigurationManager.AppSettings['test'] you can read the value from your newly created custom config file.
I encountered a problem that I have no way to parse a document standard configurations.
For example:
private string GetConfigKey(string param)
{
Configuration dllConfig = ConfigurationManager.OpenExeConfiguration(this.GetType().Assembly.Location);
AppSettingsSection dllConfigAppSettings = (AppSettingsSection)dllConfig.GetSection("appSettings");
return dllConfigAppSettings.Settings[param].Value;
}
As a result, I get the settings from the file in a form:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="host" value="mail.ololo.by"/>
</appSettings>
<configSections>
<section name="provideConfig" type="System.Configuration.DictionarySectionHandler"/>
<section name="provideMailStatus" type="System.Configuration.DictionarySectionHandler" />
</configSections>
<provideConfig>
<add key="post#gate.ololo.by" value="Mail Subject 1"/>
<add key="guga#gate.ololo.by" value="Mail Subject 2"/>
</provideConfig>
<provideMailStatus>
<add key="status1" value="send"/>
<add key="status2" value="draft"/>
<add key="status2" value="other"/>
</provideMailStatus>
</configuration>
but
Hashtable hashtable =
(Hashtable)ConfigurationManager.GetSection("provideConfig");
foreach (DictionaryEntry dictionaryEntry in hashtable)
{
Console.WriteLine(dictionaryEntry.Key+" "+dictionaryEntry.Value);
}
but that's unfortunately a configSections have a problem. I can not seem to get it.
MB, I go in the wrong direction?
P.S. Config file cannot be named "app.config" - only project dll name
Config file should be named as executable file name and ".config". Even this executable file uses this dll-file.
For example: ConSoleApplication.exe uses MyLibrary.dll. Then config file must be named ConSoleApplication.exe.config
If You need some other name for config file read this
Thank you all, I coped with the problem.
I can tell if someone will be interested.
Configuration Section Designer Codeplex
.NET Configuration Code Generator
Best regards, yauhen.
I recently started building a console version of a web application. I copied my custom sections from my web.config. to my app.config. When I go to get config information i get this error:
An error occurred creating the configuration section handler for x/y: Could not load type 'x' from assembly 'System.Configuration
The line that it is not liking is:
return ConfigurationManager.GetSection("X/Y") as Z;
Anyone run into something like this?
I was able to add
<add key="IsReadable" value="0"/>
in the appSettings and read it.
Addition:
I do actually have this defined about the custom section:
<configSections>
<sectionGroup name="x">
<section name="y" type="zzzzz"/>
</sectionGroup>
</configSections>
it sounds like your config-section handler is not defined
<configSection>
<section
name="YOUR_CLASS_NAME_HERE"
type="YOUR.NAMESPACE.CLASSNAME, YOUR.NAMESPACE, Version=1.1.0.0, Culture=neutral, PublicKeyToken=PUBLIC_TOKEN_ID_FROM_ASSEMBLY"
allowLocation="true"
allowDefinition="Everywhere"
/>
</configSection>
I had this identical issue recently. I created a custom sectiongroup for a web application(ran just fine), but when I ported this layer to a console app, the sectiongroup was failing.
You were correct in your question regarding how much of the "type" is required in your section definition. I've modified your configuration section with an example below:
<configSection>
<section
name="yourClassName"
type="your.namespace.className, your.assembly"
allowLocation="true"
allowDefinition="Everywhere" />
</configSection>
You'll notice, the type now has class name followed by assembly name. This is required for interaction outside of a web environment.
NOTE: Assembly name does not necessarily equal your namespace(for a given section).
If you want a custom config handler you have to define the class and reference it as shown by Steven Lowe. You can inherit from predefined handlers, or you can just use the value/key pair that is offered in appSetting section as you noted.
At the top of your file you require to have configSection tag with inside the section.
You can have sectionGroup too. Example:
<configuration>
<configSections>
<sectionGroup name="x">
<section name="y" type="a, b"/>
</sectionGroup>
<configSections>
</configuration>
This class works as a general custom configuration section handler for any type...
public class XmlConfigurator : IConfigurationSectionHandler
{
public object Create(object parent, object configContext, XmlNode section)
{
if (section == null) return null;
Type sectionType = Type.GetType((string)(section.CreateNavigator()).Evaluate("string(#configType)"));
XmlSerializer xs = new XmlSerializer(sectionType);
return xs.Deserialize(new XmlNodeReader(section));
}
}
In your app.config, add
<section name="NameofConfigSection" type="NameSpace.XmlConfigurator, NameSpace.Assembly"/>
And in the configuration section element, add an attribute to specify the type you want the root element deserialized into..
<?xml version="1.0" encoding="utf-8" ?>
<NameofConfigSection configType="NameSpace.NameofTypeToDeserializeInto, Namespace.Assembly" >
...
</NameofConfigSection>