如何使用物理路径OpenWebConfiguration?

发布于 2024-08-24 04:16:01 字数 279 浏览 9 评论 0原文

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

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

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

我需要使用它的功能来查找部分和读/写。

System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

将军与妓 2024-08-31 04:16:01

您必须将物理路径映射到虚拟路径。以下是您将如何做到这一点。

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, "/");
}

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, "/");
}
薔薇婲 2024-08-31 04:16:01

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");
}

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");
}
谎言 2024-08-31 04:16:01

Vadim 的答案正是我所需要的,但我遇到了与 Kieth 相同的问题,他的解决方案成功了!

我想我应该补充一点,IIS 网站名称可以是 通过调用检索

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

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);
    }
梨涡少年 2024-08-31 04:16:01

我最终使用了 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()
}

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()
}
乜一 2024-08-31 04:16:01

在瓦迪姆的回答的基础上,我发现他写的内容并不完全适合我的情况,所以我用了这个:

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

如果其他人正在尝试我正在尝试的事情并发现这个,我这样做的目的是为了得到< code>SimpleMembershipProvider,继承自 ExtendedMembershipProvider,用于与 SQLite 配合使用。为此,我通过以下链接手动创建了表: MVC4 中的 SimpleMembershipProvider,然后在我的 Global.asax 文件的 Application_Start 例程中使用此命令

WebSecurity.InitializeDatabaseConnection(ConnectionStringHelper.MyConnectionString, "System.Data.SQLite", "Users", "UserID", "Email", False)

:事实证明根本不需要我实际重写我的 web.config 文件。 (我还必须进行很多 web.config 更改,但这超出了这个问题的范围。)

Building on Vadim's answer, I found what he wrote didn't exactly work for my situation, so I used this instead:

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

In case anyone else is trying what I'm trying and finds this, the purpose of my doing this was to get SimpleMembershipProvider, which inherits from ExtendedMembershipProvider, to work with SQLite. To do that, I created the tables manually per this link: SimpleMembershipProvider in MVC4, and then used this command in my Global.asax file's Application_Start routine:

WebSecurity.InitializeDatabaseConnection(ConnectionStringHelper.MyConnectionString, "System.Data.SQLite", "Users", "UserID", "Email", False)

Which it turns out didn't require me to actually re-write my web.config file at all. (There were also a lot of web.config changes I had to do, but that is even more out of the scope of this question.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文