我有一个在IIS7中创建网站的win表单。 一个函数需要打开web.config文件并进行一些更新。 (连接字符串,smtp,模拟)
但是我没有虚拟路径,只有物理路径。
我还有什么办法可以使用WebConfigurationManager吗?
我需要使用它来查找节和读/写的能力。
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration
答案 0 :(得分:62)
您必须将physicalPath映射到virtualPath。以下是你将如何做到这一点。
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, "/");
}
答案 1 :(得分:10)
Vadim的答案在我们的开发服务器上运行得很好,但是在我们的实时服务器上轰炸了以下消息:
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. Parameter name: site
为了解决这个问题,我发现WebConfigurationManager.OpenMappedWebConfiguration
的另一个重载是将IIS网站名称作为第三个参数。结果如下:
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");
}
答案 2 :(得分:1)
我最终使用了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()
}
答案 3 :(得分:0)
在Vadim的回答基础上,我发现他所写的内容对我的情况并不完全适用,所以我改用它:
Dim connectionSettings As New ConnectionStringSettings("mySQLite", ConnectionStringHelper.MyConnectionString)
Dim dummyVirtualPath As String = "/MyApp"
Dim virtualDirMap = New VirtualDirectoryMapping(Server.MapPath("~"), True)
Dim webConfigFileMap = New WebConfigurationFileMap()
webConfigFileMap.VirtualDirectories.Add(dummyVirtualPath, virtualDirMap)
Dim mappedConfigFile = WebConfigurationManager.OpenMappedWebConfiguration(webConfigFileMap, dummyVirtualPath)
Dim config As System.Configuration.Configuration = mappedConfigFile WebConfigurationManager.OpenWebConfiguration(Server.MapPath("~") & "/")
Dim csSection As ConnectionStringsSection = config.ConnectionStrings
If csSection.ConnectionStrings("mySQLite") IsNot Nothing AndAlso csSection.ConnectionStrings("mySQLite").ConnectionString <> connectionSettings.ConnectionString Then
csSection.ConnectionStrings("mySQLite").ConnectionString = connectionSettings.ConnectionString
config.Save()
ConfigurationManager.RefreshSection(csSection.SectionInformation.Name)
End If
如果其他人正在尝试我正在尝试的内容并发现这一点,我这样做的目的是让SimpleMembershipProvider
继承自ExtendedMembershipProvider
,以便与SQLite一起使用。为此,我通过以下链接手动创建表:SimpleMembershipProvider in MVC4,然后在我的Global.asax
文件的Application_Start
例程中使用此命令:
WebSecurity.InitializeDatabaseConnection(ConnectionStringHelper.MyConnectionString, "System.Data.SQLite", "Users", "UserID", "Email", False)
事实证明,根本不需要我重新编写我的web.config文件。 (还有很多我必须做的web.config更改,但这更多地超出了这个问题的范围。)
答案 4 :(得分:0)
Vadim的回答正是我所需要的,但我遇到了与Kieth相同的问题,而他的解决方案也解决了这个问题!
我想我会补充说,IIS网站名称可以是retrieved by calling:
System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
此外,cjbarth的代码包含了一个整洁的解决方案,适用于wwwroot和Web.config位置不同的环境中的测试:
System.Web.HttpContext.Current.Server.MapPath("~");
因此,考虑到这些因素,Vadim的功能会有另外一些改进:
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);
}