When i am using a web application, the line of code below
Configuration objConfig =
ConfigurationManager.OpenExeConfiguration( ConfigurationUserLevel.None);
in class library are giving this error:
"exePath must be specified when not running inside a stand alone exe."
Previously a console application was being used, and the code could access the app.config. I tried using the System.Web.Configuration in class library but the dll was not present in the .Net tab for "Add reference".
Kindly help :)
You need to use a different configuration manager in a web context. The following code
block shows an example of how to deal with this:
System.Configuration.Configuration configuration = null;
if (System.Web.HttpContext.Current != null)
{
configuration =
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
}
else
{
configuration =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
}
I'm not sure what you're doing; but at first glance it looks like you're trying to use code written for a WinForms application in a web environment. This almost certainly will not work, since your web app won't have the permissions you need.
Try looking up how to do this in a web environment (since you seem to be dealing with config files, try searching on WEB.CONFIG to start)
I tried to use the answer from #shane but ended up with the same exception using Hangfire. This code worked for me though:
System.Configuration.Configuration configFile = null;
if (System.Web.HttpContext.Current != null)
{
configFile =
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
}
else
{
System.Configuration.ExeConfigurationFileMap map = new ExeConfigurationFileMap { ExeConfigFilename = $"{System.AppDomain.CurrentDomain.BaseDirectory}Web.Config" };
configFile = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
}
Note that editing Web.config will cause the application pool to restart!
Related
I face one issue when I tried to get something for my app.config.
So my code is simple:
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap()
{
ExeConfigFilename = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile,
};
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
string value = config.AppSettings.Settings["test"].Value; // this is working
string value2 = System.Configuration.ConfigurationManager.AppSettings["test"]; // throw an exception
The only tricky stuff here is the way of my code is loaded.
An C++ exe load my C# Assembly in an AppDomain and call my code.
I have this kind of file structure
Application.exe (C++)
myDll.dll.config
myDll.dll
The problem is some library like NLog for example call ConfigurationManager.GetSection() and this block the init of the logger.
So do you have any idea arround this ?
Thanks in advance for your help ;)
Extra Info:
Net 4.7.2
Windows 10
I have 12 projects in my solution file. There are most Windows services (ServiceProj_1, ServiceProj_2, ...) and one project is of web application (WebApp). I use log4net for logging. WebApp and ServiceProject_1, ServiceProj_2, ... have log4net configuration into web.config and app.config files respectively. We have implemented a DMZ, so the WebApp is only exposed to the other people. Now there is a requirement to use logging of those windows service projects instead of WebApp.
I have come to know that I can create a custom appender and make it possible. The catch is, there are lots of lines already written into WebApp to log a LogMessage into log file so we cannot touch those lines.
I have no idea what to do and how to do. Need help.
If the description is not understandable then please let me know I will try to explain more.
You can specify the config file and load it dynamically...
Here my config file is found at the location of FullConfigFilePath.
private Configuration Config
{
get
{
if (_Config != null) return _Config;
_Config = ConfigurationManager.OpenMappedExeConfiguration(
new ExeConfigurationFileMap()
{
ExeConfigFilename = FullConfigFilePath
}, ConfigurationUserLevel.None);
return _Config;
}
}
Once the config is loaded you can access the values from there....
For instance.....
private string BaseUrl
{
get
{
return this.Config.AppSettings.Settings["MyConfigSetting"].Value;
}
}
Hopefully you can tweak and use this sort of approach for your needs.
I initialized the interactive element with the project from the context menu of my project.
I am testing a function in C# interactive that needs to read my app.config file to get a connectionstring.
I got the next error:
No connection string named 'ccnName' could be found in the application config file.
When I use the next code, i get a null value. I suppose it is because it is not reading the app.config of my project.
ConfigurationManager.ConnectionStrings["cnnName"]
It is the only connectionstring that the default app.config has:
[data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true]
In this post from 2012 with the same topic, one engineer involved in this project said that this option was not available. I hope it is available now in 2018
So, nowadays how can i load the app.config that i want?
"Constructor" was the magic word. This may not help in your case since you've found a solution, but it might be helpful for others in the same situation.
If you inject a System.Configuration.Configuration object into the class, you don't have to rely on ConfigurationManager's static properties.
public class LibraryClass
{
private Configuration _configuration;
public LibraryClass(Configuration configuration)
{
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
}
public void FunctionUnderTest()
{
string connectionString = _configuration.ConnectionStrings.ConnectionStrings["cnnName"].ConnectionString;
// Connect to the database as you normally would.
}
}
In a console/GUI application and unit tests, load it like this to use {anything}.config:
Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Register 'configuration' as a singleton using the container of your choice.
In a web application, load it like this to use web.config:
Configuration configuration = WebConfigurationManager.OpenWebConfiguration("~/Web.config");
// Register 'configuration' as a singleton using the container of your choice.
To use it in C# Interactive, load it using the first method and provide the dependency to the class directly:
#r "System.Configuration"
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(
new ExeconfigurationFileMap() { ExeConfigFilename = #"path\to\Arbitrary.config" },
ConfigurationUserLevel.None);
var lib = new LibraryClass(configuration);
lib.FunctionUnderTest();
Note that the section properties are an extra layer deep compared to what you would normally expect.
I think it has something to do with how ConfigurationManager's static properties work with the Configuration instance.
Consider the following:
A windows service with a config file and the setting Engine.Url
The service loads an assembly into its own AppDomain
Code in the the assembly needs the setting Engine.Url
string s = ConfigurationManager.AppSettings["Engine.Url"]
does not work, s will be null.
Then I tried
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
string engineUrl = config.AppSettings["Engine.Url"];
this doesnt compile with the error:
'System.Configuration.ConfigurationElement.this[System.Configuration.ConfigurationProperty]' is inaccessible due to its protection level
Is there any way to get to the standard config file from within an AppDomain?
edit:
This doesn't work either, engineUrl will be null:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
KeyValueConfigurationElement engineUrl = config.AppSettings.Settings["Engine.Url"];
Simple answer: Yes, but it's wonky.
You have a couple options. You can set, I believe, the ConfigurationFile property of an AppDomainSetup object used when creating your AppDomain.
You can call AppDomain.SetData("APP_CONFIG_FILE", path_to_file) (see the related MSDN page)
I have a (website|windows) app and a dll(classlibrary). i want to get the root(website|windows) config file path in the dll.
I tried ConfigurationManager.OpenExeConfiguration with different assembly.get's but they always giving the dll config path.
thanks
Hi found this and it works well
Configuration config;
if (System.Web.HttpContext.Current != null &&
System.Web.HttpContext.Current.Request.PhysicalPath.Equals(String.Empty) == false)
{
config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(HttpRuntime.AppDomainAppVirtualPath);
}
else
{
config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
}
Basicly it will get web.config if its a website and it will get app.exe.config if its a windows app