如何使用物理路径打开Web配置?

时间:2010-03-03 04:21:34

标签: c#-3.0 web-config webconfigurationmanager virtual-path

我有一个在IIS7中创建网站的win表单。 一个函数需要打开web.config文件并进行一些更新。 (连接字符串,smtp,模拟)

但是我没有虚拟路径,只有物理路径。

我还有什么办法可以使用WebConfigurationManager吗?

我需要使用它来查找节和读/写的能力。

System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration

5 个答案:

答案 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);
    }