Open a parent web application's web.config file from child WCF service

2.1k views Asked by At

Here is the structure of my application. I have an asp.net web application running at the root of a website. In a child directory I have WebServices\MyWCFService\. Outlined here:

\parentapp\
\parentapp\App_Data\
\parentapp\Web.config
\parentapp\other_parent_stuff
\parentapp\WebServices\
\parentapp\WebServices\MyWCFService\
\parentapp\WebServices\MyWCFService\bin\
\parentapp\WebServices\MyWCFService\bin\MyWCFService.dll
\parentapp\WebServices\MyWCFService\Web.config (WCF's .config)
\parentapp\WebServices\MyWCFService\other_wcf_stuff

Ultimately what I need to do is open the root application's web.config to get its connection strings so the WCF service can connect to the database info provided there. From the WCF, I can get its own web.config, but I need to go up to the website's root to get that web.config. I get the root directory by doing this:

string svcDir = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
DirectoryInfo rootDir = Directory.GetParent(svcDir).Parent.Parent;
string root = rootDir.FullName;

Now apperently to open the config file, you need to use the virtual path (instead of local file system path) like so:

VirtualDirectoryMapping vdm = new VirtualDirectoryMapping(root, true);
WebConfigurationFileMap wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
Configuration config = WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");

And from there, I should be able to access the connection string by calling config.ConnectionStrings.ConnectionStrings["db_name"].

The problem is I can never get past the config declaration where I am getting an ArgumentOfOfRangeException. This was expected during testing since the root points to my VS Projects folder at C:\\Users\\me\\Documents\\Visual Studio 2012\\Projects. So I dropped a test web.config file in there, but I still get the exception. On the production servers, the path would point to the parent application's root folder, which contains the config file.

Also, keep in mind that within the WCF Service, HttpContext.Current is always null so I can't use its Request method to get the virtual path that way. Same goes for Server.MapPath. Any ideas? I am not opposed to going about this a different way, so long as ultimately, I can open the parent app's web.config.

2

There are 2 answers

1
elusive On BEST ANSWER

I finally found the right ConfigurationManger method to use in this case, where a virtual path is not needed. Here is the code:

//web config subfolder and filename
const string WEB_CONFIG = "\\Web.config";

//open parent application's web.config file to get connection string to specific database
string svcDir = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
DirectoryInfo rootDir = Directory.GetParent(svcDir).Parent.Parent;
string root = rootDir.FullName;
string webconfigPath = root + WEB_CONFIG;

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = webconfigPath;
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

string connectionString = "";
if (configuration.ConnectionStrings.ConnectionStrings["db_name"].ConnectionString.Length > 0)
{
    connectionString = configuration.ConnectionStrings.ConnectionStrings["db_name"].ConnectionString;
}

Works like a charm.

0
Icculus018 On

Here is how i ended up doing this:

    public string GetConnectionStringValueFromParent(string key)
    {
        string value = string.Empty;
        try
        {
            const string WEB_CONFIG = "\\Web.config";

            string svcDir = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
            DirectoryInfo rootDir = Directory.GetParent(svcDir).Parent;
            string root = rootDir.FullName;
            string webconfigPath = root + WEB_CONFIG;

            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = webconfigPath;
            Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

            if (configuration.ConnectionStrings.ConnectionStrings[key].ConnectionString.Length > 0)
            {
                value = configuration.ConnectionStrings.ConnectionStrings[key].ConnectionString;
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        return value;
    }