I have a win form that creates a site in IIS7. One function needs to open the web.config file and make a few updates. (connection string, smtp, impersonation)
However I do not have the virtual path, just the physical path.
Is there any way I can still use WebConfigurationManager?
I need to use it's ability to find section and read/write.
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration
You will have to map the physicalPath to a virtualPath. Here is how you would do that.
using System.Web.Configuration; //Reference the System.Web DLL (project needs to be using .Net 4.0 full, not client framework)
public static Configuration OpenConfigFile(string configPath)
{
var configFile = new FileInfo(configPath);
var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
}
Vadim's answer worked great on our dev server, but bombed out on our live server with the following message:
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. Parameter name: site
To correct this, I found another overload for WebConfigurationManager.OpenMappedWebConfiguration
that takes the IIS website name as the third parameter. The result is as follows:
public static Configuration OpenConfigFile(string configPath)
{
var configFile = new FileInfo(configPath);
var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/", "iis_website_name");
}
Vadim's answer was exactly what I needed, but I came across the same issue as Kieth, and his solution did the trick!
I thought I'd add though, that the IIS Website name can be retrieved by calling:
System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
Also, cjbarth's code included a tidy solution for those testing in environments where the location of wwwroot and Web.config can vary:
System.Web.HttpContext.Current.Server.MapPath("~");
So with these in mind another slight improvement on Vadim's function would read:
public static Configuration GetWebConfig() {
var webConfigFile = new FileInfo("Web.config");
var wwwRootPath = HttpContext.Current.Server.MapPath("~");
var vdm = new VirtualDirectoryMapping(wwwRootPath, true, webConfigFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
var siteName = HostingEnvironment.ApplicationHost.GetSiteName();
return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/", siteName);
}
I ended up using Powershell.
$file = "D:\Applications\XXX\Private\XXX\XXXX\web.config"
$configurationAssembly = "System.Configuration, Version=4.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"
[Void] [Reflection.Assembly]::Load($configurationAssembly)
$filepath = New-Object System.Configuration.ExeConfigurationFileMap
$filepath.ExeConfigFileName = $file
$configuration = [System.Configuration.ConfigurationManager]::OpenMappedExeConfiguration($filepath,0)
$section = $configuration.GetSection("appSettings")
Write-Host "Set the Protection Provider"
if (-not $section.SectionInformation.IsProtected)
{
$section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider")
$configuration.Save()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With