log4net for IIS WCF service with separate config - c#

I want to use log4net for a WCF Service that is hosted in IIS.
But to change settings easily, I want to use a separate config file.
So I added to the Web.Config (and App.config of the WCF Service library)
<appSettings>
<add key="log4net_config" value="log4net.config" />
</appSettings>
But this leads to the current directory of IIS, which is
C:\Windows\System32\inetsrv
And there will never be my log4net.config file.
But I want to configure log4net something like
var configFile = ConfigurationManager.AppSettings["log4net_config"];
var fileInfo = new FileInfo(configFile);
XmlConfigurator.ConfigureAndWatch(fileInfo);
How can I configure a directory that fits this needs?

First of all you could put full path to your log4.net config file.
Secondly you can use System.Web.Hosting.HostingEnvironment.MapPath for example to resolve path like "~/log4net.config"

Related

Read web.config from library consumed by the webapplicaion deployed using IIS

I have a web application deployed on IIS. This web application is consuming a library which wants to access the Web.config.
Example :
Foo.dll is the web application deployed on IIS
Foo.Utility.dll is consumed by Foo.dll
There is a piece of code in Foo.Utility namepsace which wants to access the web.config from Foo application and read the config values
Configuration config = WebConfigurationManager.OpenWebConfiguration(null);
string cacheDir = config.AppSettings.Settings["abc"].Value;
Currently config.FilePath = C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config
Changed my code to :
Configuration config = WebConfigurationManager.OpenWebConfiguration(Assembly.GetCallingAssembly().Location);
string cacheDir = config.AppSettings.Settings["abc"].Value;
Now my Assembly.GetCallingAssembly().Location is : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\62f5c902\849205ff\assembly\dl3\c28d4647\10e128d3_7449d001\foo.dll
Can someone help me to understand how to read the web.config from the place where my application is deployed using IIS?
For more information or if the question is not clear then comment below. Will update it
You have to use ConfigurationManager from System.Configuration. First, you'll have to add a reference to System.Configuration.dll assembly, and then use it like this:
using System.Configuration;
...
string valueOfAbc = ConfigurationManager.AppSettings["abc"];
ConfigurationManager will read the config file from the application's host. In your case, the web.config file.
Reference:
ConfigurationManager Class
Application Configuration Files

WCF File Not Found when hosted on IIS

I have a few XML files in my WCF service that are mapped like
\\servermain\D$\apps\dataservice\bin\Type\FileName.xml
\\servermain\D$\apps\dataservice\bin\Type\Config\ConfigFile.xml
I refer to these files in my program by using
.\\Type\\FileName.xml
.\\Type\\Config\\ConfigFile.xml
When i run my application through the console as a service it works completely fine... when i deploy it to the IIS server i get an error saying the file can't be found...
Here is a bit of text from my result (My WCF service spits out JSON)
"Message":"IO Exception C:\\Windows\\SysWOW64\\inetsrv","Detail":"File does not exist: .\\Type\\Config\\ConfigFile.xml"
I used System.Environment.CurrentDirectory to get the current directory for the error above.
How do i configure it so that my application path is actually
\\servermain\D$\apps\dataservice\bin\
I would prefer if I wouldn't have to hardcode the actual path of the file, because developers would be running this service through their local machines as well.
I would prefer if I wouldn't have to hardcode the actual path of the file, because developers would be running this service through their local machines as well.
That's what you are doing right now. A possible way to resolve this hardcoded paths is pretty easy:
Every WCF service comes with a config file. You can easily add the appSettings element to your config and specify absolute or relative paths to any additional file.
E.g. for executing the console:
<appSettings>
<add key="ConfigFile" value=".\\Type\\Config\\ConfigFile.xml" />
</appSettings>
And instead for the IIS hosted config:
<appSettings>
<add key="ConfigFile" value="\\servermain\D$\apps\dataservice\bin\Type\Config\ConfigFile.xml" />
</appSettings>
You can then access those values via the System.Configuration.ConfigurationSettings class.
UPDATE:
The System.Configuration.ConfigurationSettings is marked as obsolete. Instead, the System.Configuration.ConfigurationManager or System.Configuration.WebConfigurationManager should be used.

Read config file from asp.net

I'm creating a web application, which calls a DLL to run unit tests, I also have another DLL(DataAccessLayer) which performs connections and performs queries to SQL which references the main DLL. Both the DLLs use the same config file to read settings.
When running application from VS, the application is working fine. However when the web app is deployed to IIS, it seems the DLLs are unable to read the settings from the config file.
After some research I found that I might have to explicitly define the configuration elements in the web.config file, however I don't know how to implement this. Can someone please point me in the right direction?
I'm actually retrieving the settings using the ConfigurationManager with the following code:-
public string GetValue(string key)
{
var appConfig = ConfigurationManager.OpenExeConfiguration("path to dll");
strKeyValue = appConfig.AppSettings.Settings[key].Value;
return strKeyValue;
}
Thanks.
Use WebConfigurationManager.AppSettings["HelloWorldKey"]; to read AppSettings from the web.config.
Just set all the appSettings values used by the DLL you mention, directly in the web.config PRIOR to deploying the app. You don't need to modify this at run-time (and you shouldn't anyway, since any modification to the web.config will cause the application to restart)
Add the connectionstring or AppSetting or ApplicationSettings used in you app.config into your web.config, I understand this is a manual task but is the only way that the config will read the settings.
Use following code to access connection string
string filePath= WebConfigurationManager.AppSettings["Pathfile"].ToString();
Web config Fie
<configuration>
....
<appSettings>
<add key="Pathfile" value="Path to dll"/>
</appSettings>
....
</configuration>

How to access a connection string from within a library

I have a web project (mvc) and data access layer in a separated class library project. I need to access to a connection string in app.config which sits in that library project.
ConfigurationManager.ConnectionStrings[0].ConnectionString pulls something strange. I don't have this kind of settings neither in the library's config nor in the web project's config files.
the App.config looks like that:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="DALConnectionString" connectionString="User ID=sa;Password=pass;Initial Catalog=db;Data Source=srv\SQL2005;" />
</connectionStrings>
</configuration>
Your library should use dependency injection in this case for inversion of control.
Your class in the data access layer (DAL) library should take the connection string as a constructor argument or a property value.
This will make sure that your DAL can be used in other projects also and is not tied to your your mvc web application.
Let the code which will consume the DAL read the connection string from the config file and inject it into your class's constructor.
By default, a class library can't access a config file.
The client of the class library, in this case your web project, can provide config settings.
Therefore, put all the relevant settings, the connection strings, in the web's config file. The ConfigurationManager code in the class library will use the web projects config settings.
you should add the fragment shown above in the web.config then at runtime the configuration manager will use it even if running inside your class library.
You cannot access a app.config for a DLL.
app.config only works for the entry point assembly or web.config for a web project.
Try copying the connection to the entry point config or load the config by parsing the configuration XML - not recommended.

Relocating app.config file to a custom path

Is it possible to relocate the whole App.Config file to a custom path?
It seems a bit odd that the config file resides in the same folder as the exe, with Windows' new approcah of saving all program settings in c:\ProgramData and all.
An additional requirement we have is to programatically specify where to find the app.config file. The reason for this being that we spawn different service instances from the same exes, and would like to store each service's app.config in that service's settings folder under c:\ProgramData\\.
If still relevant, we have used the following I found on another suggested answer to another question here on Stack Overflow...
AppDomain.CurrentDomain.SetData ("APP_CONFIG_FILE", "path to config file")
Worked great for us when we had issues loading app.config from DLL only...
Each AppDomain has/can have its own configuration file. The default AppDomain created by CLR host uses programname.exe.config; if you want to provide your own configuration file, create separate AppDomain. Example:
// get the name of the assembly
string exeAssembly = Assembly.GetEntryAssembly().FullName;
// setup - there you put the path to the config file
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = System.Environment.CurrentDirectory;
setup.ConfigurationFile = "<path to your config file>";
// create the app domain
AppDomain appDomain = AppDomain.CreateDomain("My AppDomain", null, setup);
// create proxy used to call the startup method
YourStartupClass proxy = (YourStartupClass)appDomain.CreateInstanceAndUnwrap(
exeAssembly, typeof(YourStartupClass).FullName);
// call the startup method - something like alternative main()
proxy.StartupMethod();
// in the end, unload the domain
AppDomain.Unload(appDomain);
Hope that helps.
I know this is an old question, but for those who just want to have their app.config in a different location then their binary output build location, the following works as microsoft intended it (and thus no need re-read and re-write the file to disk)
Define an app.config as you always do.
Define another config file where you want to have the actual configuration file
Change the app.config so that it refers to the configuration file
At runtime the settings from the configuration file will override the settings in the app.config (if present). And you are done.
Example app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<appSettings file="..\Config\settings.config">
<add key="port" value="1001"/>
</appSettings>
</configuration>
Note the file="..\Config\settings.config". You are completely free to define the path to the location where you want your users to change settings.
Example of the actual configuration file
<?xml version="1.0" encoding="utf-8"?>
<appSettings>
<add key="port" value="1234"/>
</appSettings>
At runtime the setting port will have the value 1234.
More info see msdn
This worked for me.. (taken from http://msdn.microsoft.com/en-us/library/system.configuration.appsettingssection.aspx)
// open config
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// update appconfig file path
config.AppSettings.File = "C:\\dev\\App.config";
// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);
// Force a reload in memory of the changed section.
ConfigurationManager.RefreshSection("appSettings");
Then when you call
NameValueCollection settings = System.Configuration.ConfigurationManager.AppSettings;
or any operation to fetch the app config, the new path is used.
Hope this might help someone else who has same problem!
I am sorry if I misunderstand your request but can you not use
ConfigurationManager.OpenExeConfiguration Method (String)
Based on the change, is it possible that you can use
AppDomainSetup.ConfigurationFile Property
This is an ancient question, but I ran into this same problem and came up with a hacky workaround from a few minutes in reflector:
static public class ConfigHack {
static public void OverrideAppConfig(string path) {
((AppDomainSetup)
typeof(AppDomain)
.GetField("_FusionStore", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(AppDomain.CurrentDomain))
.ConfigurationFile = path;
}
static public void ResetConfigManager() {
typeof(ConfigurationManager)
.GetField("s_initState", BindingFlags.Static | BindingFlags.NonPublic)
.SetValue(null, 0);
}
}
I've only used it on .NET2, but it looks the same in 4 in reflector. Of course I wouldn't recommend shipping this :P I only use it for quick internal things.
You could use astander's approach of calling OpenExeConfiguration. If you literally want to relocate your config file, you'll have to create your own app domain. In the process of setting up your app domain you get the chance to specify where the config file is located.
BTW, .NET config files aren't great for configuration, at least not the sort that users can modify: they're not like INI files or the registry. If you want flexibility over where your configuration comes from you're better off storing it separately.
If u use the registry, your problem can be resolved.
MSDN probably would help...
The element
simplifies servicing for component
assemblies. If one or more
applications use an assembly that has
a configuration file residing in a
well-known location, the configuration
files of the applications that use the
assembly can use the
element to
include the assembly configuration
file, rather than including
configuration information directly.
When the component assembly is
serviced, updating the common
configuration file provides updated
configuration information to all
applications that use the assembly

Categories

Resources