Custom config file elements in ASP.NET: `Property is not a ConfigurationElement' - c#

I'm attempting to implement my first go-around of reading custom configuration elements from an ASP.NET web.config file. It seems pretty simple to me, yet I'm receiving a run-time `Property is not a ConfigurationElement' error. Here's my code:
The web.config file sections:
<?xml version="1.0" encoding="utf-8" ?>...
<configuration>
...
<section name="appConfig" type="ParticipationManagement.AppConfig" allowDefinition="Everywhere" allowLocation="true" requirePermission="false" />
</configSections>
...
<appConfig>
<startRecertVFC>2/15</startRecertVFC>
</appConfig>
</configuration>
The handler:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Web;
namespace ParticipationManagement
{
public class AppConfig : ConfigurationSection
{
[ConfigurationProperty("startRecertVFC", IsRequired = false)]
public DateTime RecertVFCStart
{
get
{
string start = (string)this["startRecertVFC"];
string year = DateTime.Now.Year.ToString();
DateTime start_date;
if (DateTime.TryParse(start + "/" + year, out start_date))
{
return start_date;
}
else
{
return DateTime.Today;
}
}
set
{
this["startRecertVFC"] = value;
}
}
}
}
And my invocation in page code:
protected void Page_Init(object sender, EventArgs e)
{
...
AppConfig config = (AppConfig)System.Configuration.ConfigurationManager.GetSection("appConfig");
RecertVFCStart = config.RecertVFCStart;
}
Seems very clean and straight-forward to me, but I'm getting that troubling error at runtime and I cannot narrow it down since I have no experience with this.
Sorry in advance: I see plenty of other posts about this but all seem to address more advanced/complex issues than what I'm trying to accomplish, which is nothing more than embedding a few app-specific values in an external file...

Change your config setting like an example shown below
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="appConfig" type="ParticipationManagement.AppConfig" allowDefinition="Everywhere" allowLocation="true" requirePermission="false"/>
</configSections>
<appConfig startRecertVFC="5/1/2015 8:30:52 AM" />
</configuration>
Try to make the following change in AppConfig file
string start = this["startRecertVFC"].ToString();
Let us know if this solves your problem

Related

app.config not updating when I use configmanager

I have these pieces of code:
string theme = ConfigurationManager.AppSettings["Theme"];
private void ChangeTheme(string Name)
{
if(Name=="Light")
{
Form1.ActiveForm.BackColor = System.Drawing.Color.White;
Form.ActiveForm.ForeColor = System.Drawing.Color.Black;
}
if (Name == "Dark")
{
Form1.ActiveForm.BackColor = System.Drawing.Color.Black;
Form.ActiveForm.ForeColor = System.Drawing.Color.DarkOrange;
}
Configuration cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
cfg.AppSettings.Settings["Theme"].Value = Name;
cfg.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}
My app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="Volume" value="7"/>
<add key="Keyval" value="X"/>
<add key="Theme" value="Light"/>
</appSettings>
</configuration>
Basically, when I press the radio buttons it changes the theme and sends the string to changetheme(), but it does not update in the app.config.
Are you running it in debug?
Probably you are looking at the wrong file. While debugging visual studio uses the config file from the bin\Debug so it would not update the App.config from the solution.
Instead of using == for comparison, I would use the String Equals Method:
Name.Equals("Light")
While I'd bet that it's not the issue, it's good practice and maybe you get lucky and that is the issue.

How to read and update value in xml file via C sharp?

I have the xml file is following manner :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Conn" providerName="System.Data.SqlClient"
connectionString="Data Source=machine_name; Initial Catalog=database_name; User ID=id; Password=password" />
</connectionStrings>
</configuration>
In above xml file i want to change the value of password.
Code i have tried is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;
using System.Xml.Linq;
namespace ConsoleApplication85
{
class Program
{
static void Main(string[] args)
{
XDocument xdoc = XDocument.Load(#"filepath.xml");
var element = xdoc.Elements("Password").Single();
element.Value = "new password";
xdoc.Save(#"filepath.xml");
}
}
}
The best way to change the application configuration is through the methods of the ConfigurationManager class, not through XmlDocument methods..
See this question:
Change connection string & reload app.config at run time

Handling File Naming Convention from Configuration File

I have attempting to implement a file naming convention in my program. For example I have a configuration file such as below:
MyConfig.conf
# File naming convention for output-file
[Field1][Field3][Field2]
'FieldX' corresponds with string within the program - so for example a program would read the configuration file and format the strings as follows in the program:
Field1Value Field2Value Field3Value
Are there any preferred ways to do this kind of thing in C#?
Easiest way I can think of is to use app settings. The app settings contain the string format that you need. Then you just use that string format.
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _16852548
{
class Program
{
static void Main(string[] args)
{
NameValueCollection appSettings = ConfigurationManager.AppSettings;
string field1Value = "Filename";
string field2Value = ".";
string field3Value = "txt";
string fileFormat = appSettings["FileNameFormat"];
Console.WriteLine(string.Format(fileFormat, field1Value, field2Value, field3Value));
}
}
}
Then the config file can be:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="FileNameFormat" value="{0}{2}{1}"/> <!-- follow string.Format syntax -->
</appSettings>
</configuration>

perfmon using EntLib - no instance in perfmon

We are in need to add performance monitoring to our application.
For the prototype I've created a sample project, which I'm trying to get into work.
I'm trying to use policyInjection for the performance counters, so we'll be able to turn on and off the performance monitoring in the production environment.
So far I can see the actual category in perfmon, but I cannot see any instances (see image), even I'm pretty sure the application is running and instance exists, as you can see in attached sources.
I've tried a lot of things, also googled around, but didn't find any usable solution or clue what to look for.
Application is created as consoleApplication
You can also download a zipped project for VS here:
http://dl.dropbox.com/u/19457132/stackOverflow/Mpd.Instrumentation.PerformanceCounter.zip
Here are my sources.
Program.cs
using System;
using System.Collections;
using System.Configuration.Install;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Installers;
namespace Mpd.Instrumentation.PerformanceCounter
{
class Program
{
static void Main(string[] args)
{
//RemoveCounters();
InstallCounters();
MyCounters myCounter = PolicyInjection.Create<MyCounters>();
for (int i = 0; i < 100000000; i++)
{
myCounter.SampleMethod(i);
}
Console.ReadLine();
}
public static void InstallCounters()
{
PerformanceCountersInstaller installer = new PerformanceCountersInstaller(new SystemConfigurationSource());
IDictionary state = new Hashtable();
installer.Context = new InstallContext();
installer.Install(state);
installer.Commit(state);
Console.WriteLine("Performance counters have been successfully installed. Press enter to continue");
Console.ReadLine();
}
private static void RemoveCounters()
{
PerformanceCountersInstaller installer = new PerformanceCountersInstaller(new SystemConfigurationSource());
installer.Context = new InstallContext();
installer.Uninstall(null);
Console.WriteLine("Performance counters have been successfully removed. Press enter to continue.");
Console.ReadLine();
}
}
}
MyCounters.cs
using System;
using System.Threading;
namespace Mpd.Instrumentation.PerformanceCounter
{
public class MyCounters : IPerformanceCounter
{
public void SampleMethod(int i)
{
Console.WriteLine(i);
Thread.Sleep(50);
}
}
}
IPerformanceCounter.cs
using System;
namespace Mpd.Instrumentation.PerformanceCounter
{
public class IPerformanceCounter : MarshalByRefObject
{
}
}
And finally app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="policyInjection" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.PolicyInjectionSettings, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
<section name="instrumentationConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Common.Instrumentation.Configuration.InstrumentationConfigurationSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
</configSections>
<policyInjection>
<policies>
<add name="SampleCountersPolicy">
<matchingRules>
<add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.MethodSignatureMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
match="SampleMethod" ignoreCase="true" name="Method Signature Matching Rule" />
</matchingRules>
<handlers>
<add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers.PerformanceCounterCallHandler, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
categoryName=".aaaTest" instanceName="Default" useTotalCounter="true"
incrementNumberOfCalls="true" incrementCallsPerSecond="true"
incrementAverageCallDuration="true" incrementTotalExceptions="true"
incrementExceptionsPerSecond="true" order="1" name="Performance Counter Call Handler" />
</handlers>
</add>
</policies>
</policyInjection>
<instrumentationConfiguration performanceCountersEnabled="true"
applicationInstanceName="Default" />
</configuration>
Since the SampleMethod accepts a parameter you need to add that to the matching rules configuration:
<matchingRules>
<add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.MethodSignatureMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
match="SampleMethod" ignoreCase="true" name="Method Signature Matching Rule">
<parameters>
<parameter name="i" typeName="System.Int32" />
</parameters>
</add>
</matchingRules>
Without the parameter the matching rule does not match so the call handler is not invoked. If you modify the configuration you should see the instances in perfmon.

Custom config file for provider configuration

I'm building a custom provider and would like to know how to specify a different configuration file (ex: MyProvider.Config) for my provider to pick the configuration from. By default it is using Web.Config.
Can I specify the path to the custom config file in MyProviderConfiguration class?
Example:
internal class MyProviderConfiguration : ConfigurationSection
{
[ConfigurationProperty("providers")]
public ProviderSettingsCollection Providers
{
get
{
return (ProviderSettingsCollection)base["providers"];
}
}
[ConfigurationProperty("default", DefaultValue = "TestProvider")]
public string Default
{
get
{
return (string)base["default"];
}
set
{
base["default"] = value;
}
}
}
I am not too sure what you want to do. If you just want to load up a config file from a different location you can do the following:
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
configFileMap.ExeConfigFilename = "<config file path>";
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
MyProviderConfiguration customConfig = (MyProviderConfiguration)config.GetSection("
configSectionName");
If you just want to put your custom configuration inside a separate file you can do this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="myProviderConfiguration" type="Namespace.MyProviderConfiguration, AssemblyName" />
</configSections>
<myProviderConfiguration configSource="configFile.config" />
</configuration>
And then your configFile.config file would contain:
<?xml version="1.0" encoding="utf-8"?>
<myProviderConfiguration Default="value">
<Providers>
<Provider />
</Providers>
</myProviderConfiguration>
If that doesn't help can you clarify your question further.

Categories