ConfigurationProperty is inaccessible due to its protection level - c#

I wanna read/write (and save) application's configuration file in program
The app.config is like this:
<configuration>
<configSections>
<section name="AdWordsApi" type="System.Configuration.DictionarySectionHandler" requirePermission="false"/>
</configSections>
<AdWordsApi>
<add key="LogPath" value=".\Logs\"/>
...
</AdWordsApi>
</configuration>
When I use ConfigurationManager.GetSection to read the app.config, it works:
var adwords_section = (System.Collections.Hashtable) System.Configuration.ConfigurationManager.GetSection("AdWordsApi");
Console.WriteLine((string)adwords_section["LogPath"]);
But when I use ConfigurationManager.OpenExeConfiguration:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
ConfigurationSection section = config.GetSection("AdWordsApi");
Console.WriteLine(section["LogPath"]);
I always get this error:
'System.Configuration.ConfigurationElement.this[System.Configuration.ConfigurationProperty]'
is inaccessible due to its protection level
But as I know, GetSection cannot save configuration at program runtime, Like I said at beginning: I wanna save configuration at program runtime, So I have to use OpenExeConfiguration.
I have googled for long time, what I found is to use AppSettings, but what I use is custom section..
Anyone could explain why this "ConfigurationProperty is inaccessible" error occured? Thanks
Edit:
I have set copy local of System and System.Configuration to true

string key_value = refconfig.AppSettings.Settings["key_name"].Value;

You can use this article.
Edit:
you can use config:
<configSections>
<section name="AdWordsApi.appSettings" type="System.Configuration.AppSettingsSection" />
</configSections>
<AdWordsApi.appSettings>
<add key="LogPath" value=".\Logs\"/>
</AdWordsApi.appSettings>
this code:
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
var settings = config.GetSection("AdWordsApi.appSettings") as AppSettingsSection;
if (settings != null) Console.Write(settings.Settings["LogPath"].Value);
Console.ReadLine();
Also You can use this article.

I'm not sure if it will work for what you are trying to do, but have you tried using ConfigurationUserLevel.None instead?

Related

Modifying appSettings "file" attribute at runtime

string appConfPath = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).FullName;
string fullPath = appConfPath + "\\Local\\RandFolder\\ThisOne\\application.settings.xml";
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.File = fullPath;
config.AppSettings.Settings.Add("Password", "djydyjdjtdtyjddj");
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
var temp = config.AppSettings;
I am currently trying to set the "file" attribute of my appSettings configuration and reference XML's included settings at runtime. I am unable to do this before compile because the XML settings file will change based on the local machines settings.
However, after making the above changes, the temp variable only contains the "Password" item and is unable to retrieve the other settings located in the included file path. I know the file attribute is being set but for some reason the referenced setting are still hidden. The application.settings.xml file looks like this...
<?xml version="1.0" encoding="utf-8"?>
<appSettings>
<add key="ServerLocation" />
<add key="PerforceURI" value="yuhsgbyluvgblsg" />
</appSettings>
Any help is greatly appreciated!
I won't try to critique what you are doing, but provide you with a simple explanation of what you are seeing.
ConfigurationManager.RefreshSection refreshes the section in the Configuration instance used by the static ConfigurationManager. It does not effect the Configuration instance you created by calling OpenExeConfiguration; for that to occur you would need to call OpenExeConfiguration again.

How to modify custom sections of the web.config file, from a generic .NET application?

I have a WinForm derived application (note NOT an ASP.NET web application) from where I need to modify a custom section of an arbitrary web.config file. As an example, if my web.config is something like this:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- General web.config stuff follows -->
<system.web>
<httpRuntime executionTimeout="110" maxRequestLength="1024" requestValidationMode="2.0" />
</system.web>
<MyConfigSection>
<GeneralParameters>
<param key="Var1" value="value1" />
</GeneralParameters>
</MyConfigSection>
</configuration>
I can easily modify some default parameter, say, for maxRequestLength I'd do this and it would work:
//Path to the web.config file
string strWebConfigFile = #"C:\My files\web.config";
//Convert absolute path to virtual
var configFile = new FileInfo(strWebConfigFile);
var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
//Open web.config file
System.Configuration.Configuration config =
System.Web.Configuration.WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
if (config != null)
{
System.Configuration.ConfigurationSection system_web =
config.GetSection("system.web/httpRuntime");
PropertyInformation pi = system_web.ElementInformation.Properties["maxRequestLength"];
pi.Value = 1234; //Set new value
//Save
config.Save(ConfigurationSaveMode.Modified);
}
The issue is when I try to modify my custom section. Say, if I wanted to rewrite Var1 parameter's value with value2, the following:
System.Configuration.ConfigurationSection genParams = config.GetSection("MyConfigSection/GeneralParameters");
returns null and if I call it with just MyConfigSection, it gives me this exception:
An error occurred creating the configuration section handler for
MyConfigSection: Could not load type 'MyWebApp.Configuration' from
assembly 'System.Web, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=N'.
What shall I do here to add that "configuration section handler"?
You have to open it up with XmlDocument, and work with it, sorry. That is how we cracked this nut - sorry I'm not at liberty to give you the code.

Using ConfigurationManager's OpenExeConfiguration and GetSection,(Custom config file and section)

Is it possible to retrieve a custom configuration section from a config file other than the app.config or web.config.
I tried using the System.Configuration.ConfigurationManager's OpenExeConfiguration and GetSection method calls together but without luck. My intention is to define custom configuration sections for interchangeable process adapters and contain the custom config section in a separate config file other than app.config and web.config. I see plenty of examples for appsettings and connectionstrings.
static private DigiKeyReadTaskConfigSection digiKeyReadTaskConfigSection;
static DigiKeyReadTaskConfigSection DigiKeyReadTaskConfigSection {
get {
if (digiKeyReadTaskConfigSection == null) {
digiKeyReadTaskConfigSection = (DigiKeyReadTaskConfigSection)ConfigurationManager.OpenExeConfiguration("ReadTask.config").GetSection("DigiKeyReadTaskConfigSection");
}
return digiKeyReadTaskConfigSection;
}
}
The digiKeyReadTaskConfigSection = (DigiKeyReadTaskConfigSection)ConfigurationManager.OpenExeConfiguration call seems to be working however the (DigiKeyReadTaskConfigSection)ConfigurationManager.OpenExeConfiguration("ReadTask.config").GetSection("DigiKeyReadTaskConfigSection") returns null.
The ReadTask.config file lives in the bin file of the App:
<configuration> <configSections>
<section name="DigiKeyReadTaskConfigSection" type="DataReadInc.WebSiteRead.TaskConfigSection.DigiKeyReadTaskConfigSection, DataReadInc.WebSiteRead" />
<section name="ArrowReadTaskConfigSection" type="DataReadInc.WebSiteRead.TaskConfigSection.ArrowReadTaskConfigSection, DataReadInc.WebSiteRead" /> </configSections> <DigiKeyReadTaskConfigSection DigiKeySiteURL="http://search.digikey.com/scripts/DkSearch/dksus.dll?WT.z_header=search_go&lang=en&site=us&keywords="
SiteLogInURL="https://ordering.digikey.com/RegisteredUser/Login.aspx,formName=" SiteLoginId="X" SiteLoginPassword="X" /> <ArrowReadTaskConfigSection ArrowAmericaSiteURL="http://components.arrow.com/part/search/"
SiteLoginURL="http://components.arrow.com/login/processlogin#" SiteLoginId="X" SiteLoginPassword="X" /> </configuration>
I have seen this type of setup with Spring.Net and a J2EE implementation so I am sure it is possible. I can just put my custom config sections in the App.config or web.config file, however it would be significantly cleaner for them to exist in their own config file.
Use ConfigurationManager.OpenMappedExeConfiguration(). OpenExeConfiguration relates to a certain exe.

How to open a config file app settings using ConfigurationManager?

My config file is located here:
"~/Admin/Web.config"
I tried opening it via the below code but it didn't work:
var physicalFilePath = HttpContext.Current.Server.MapPath("~/Admin/Web.config");
var configMap = new ConfigurationFileMap(physicalFilePath);
var configuration = ConfigurationManager.OpenMappedMachineConfiguration(configMap);
var appSettingsSection = (AppSettingsSection)configuration.GetSection("appSettings");
when appsettings line runs, it throws the below error message:
Unable to cast object of type 'System.Configuration.DefaultSection' to type 'System.Configuration.AppSettingsSection'.
My Web.Config looks like below:
<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<appSettings>
<add key="AdminUsername" value="Test1"/>
<add key="AdminPassword" value="Test2"/>
</appSettings>
<connectionStrings></connectionStrings>
</configuration>
How could I get the appsettings?
For web-app, you need to use System.Web.Configuration.WebConfigurationManager class and no need to set absolute path.
var web=System.Web.Configuration.WebConfigurationManager
.OpenWebConfiguration("~/admin/web.config");
String appValue=web.AppSettings.Settings["key"].Value;
If you are looking for adding some stuff to the Web.config, and then reading it from the code.
What you need is Custom Configuration Sections in Web.config
Look here:
How do I define custom web.config sections with potential child elements and attributes for the properties?
and here:
Creating Custom Configuration Sections in Web.config - 4GuysFromRolla.com

How to write to the main exe's .config userSettings section?

Is there any supported API in .NET 2.0 for writing to the userSettings section of the main exe's .config file?
The scenario is:
Winforms 2.0 application.
I have a setting (a database connection string, if you need to know) that has user level scope. This means that each user has a user.config file created by .net when the user saves the value of the setting.
For new users that run the application for the first time, the main exe's .config file of the application contains a default value in the user settings section. This section is created by visual studio when the setting is created in the Settings tab of the project properties.
Now, I want to allow any Administrator user in the computer to be able to change the default value for new users. Only Administrators will have this option, because regular users don't have permission to write to the main exe's .config file anyway.
I have found how to write user settings to the user's .config file, and how to write to the appSettings section of the main .config file. But my googling has failed when trying to find out how to write to the userSettings section of the main .config
Is my only chance failing back to System.Xml and do it manually loading the .config in an XmlDocument?
After some research I came up with this solution. It is a bit low level, but still goes through the .NET configuration API without having to manually parse the .config file.
static void SaveUserSettingDefault(string clientSectionName, string settingName, object settingValue)
{
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// find section group
ConfigurationSectionGroup group = config.SectionGroups[#"userSettings"];
if (group == null) return;
// find client section
ClientSettingsSection clientSection = group.Sections[clientSectionName] as ClientSettingsSection;
if (clientSection == null) return;
// find setting element
SettingElement settingElement = null;
foreach (SettingElement s in clientSection.Settings)
{
if (s.Name == settingName)
{
settingElement = s;
break;
}
}
if (settingElement == null) return;
// remove the current value
clientSection.Settings.Remove(settingElement);
// change the value
settingElement.Value.ValueXml.InnerText = settingValue.ToString();
// add the setting
clientSection.Settings.Add(settingElement);
// save changes
config.Save(ConfigurationSaveMode.Full);
}
Given a .config with the following content:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="MyAssembly.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<MyAssembly.Properties.Settings>
<setting name="SqlConnectionString" serializeAs="String">
<value>Server=(local);Database=myDatabase;Integrated Security=true;</value>
</setting>
</MyAssembly.Properties.Settings>
</userSettings>
</configuration>
You would use it like this:
if (RunningAsAdmin) // save value in main exe's config file
{
SaveUserSettingDefault(#"MyAssembly.Properties.Settings", #"SQLConnectionString", theNewConnectionString);
}
else // save setting in user's config file
{
Settings.Default. SQLConnectionString = theNewConnectionString;
Settings.Default.Save();
}
I think yes - manually writing to the .config file is the only way.
Or you can let the administrator edit the .config-file himself.

Categories

Resources