I am having an issue somewhat similar to this question: C#: Config file error
BACKGROUND
My situation is this: I am using NLog and I have setup a Database target. My app shows an installation page on first run from which I build a connection string for other purposes but would also like to save that same connection string to the NLog.config file. After much searching it would appear that NLog can be changed programatically, but for whatever reason cannot save the changes back to the .config file. Therefore, my plan was to simply do the following:
WHAT I HAVE TRIED
Change the connectionString attribute to simply be connectionStringName instead. Example: connectionStringName="NLogConnection"
Move the
<connectionStrings>
element from my Web.config to a separate file: ConnectionStrings.config.Update web.config accordingly:
<connectionStrings configSource="ConnectionStrings.config" />
- Write code as follows:
string filePath = HostingEnvironment.MapPath(Path.Combine(httpRequest.ApplicationPath, "ConnectionStrings.config"));
var fileMap = new ExeConfigurationFileMap
{
ExeConfigFilename = filePath
};
var configFile = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
configFile.ConnectionStrings.ConnectionStrings["NLogConnection"].ConnectionString = connectionString;
configFile.Save();
OUTCOME
Seemed like a nice plan. However.. the code above throws an error about not having a <configuration>
tag and if I add that tag, the site throws an error about the tag being there! No win situation here... does anyone have any ideas on how to solve this one? Ideally it would be nice if there was a way to properly modify external .config files which are only a part of the main web config. I may have to revert to manually reading/writing the raw XML.. but I would prefer not to if there's a better/more elegant way.
SOLUTION
Many thanks to @Julian; I now have a working solution. I added this in my Global.asax:
private static void TryUpdateNLogConnectionString(string connectionString)
{
try
{
var target = LogManager.Configuration.FindTargetByName("database");
DatabaseTarget databaseTarget = null;
var wrapperTarget = target as WrapperTargetBase;
// Unwrap the target if necessary.
if (wrapperTarget == null)
{
databaseTarget = target as DatabaseTarget;
}
else
{
databaseTarget = wrapperTarget.WrappedTarget as DatabaseTarget;
}
databaseTarget.ConnectionString = connectionString;
}
catch { }
}
You can change settings programmatically in NLog, but you can't serialize those settings to the XML, yet.
What you can do:
<appSettings>
when changed<appSettings>
when needed.eg
Edit the connectionstring when needed in NLog: