【问题标题】:How to OpenWebConfiguration with physical path?如何使用物理路径打开WebConfiguration?
【发布时间】:2011-01-23 01:10:23
【问题描述】:

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

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

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

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

System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration

【问题讨论】:

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


    【解决方案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()
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • 对我来说,我必须使用public static System.Configuration.Configuration OpenConfigFile(string configPath)
        【解决方案4】:

        根据 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
        

        如果其他人正在尝试我正在尝试的东西并发现了这个,我这样做的目的是让继承自 ExtendedMembershipProviderSimpleMembershipProvider 与 SQLite 一起使用。为此,我根据此链接手动创建了表:SimpleMembershipProvider in MVC4,然后在我的Global.asax 文件的Application_Start 例程中使用此命令:

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

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 2017-06-23
            • 2018-10-28
            • 2011-09-20
            • 1970-01-01
            • 1970-01-01
            • 2021-05-31
            • 1970-01-01
            • 1970-01-01
            • 2017-11-16
            相关资源
            最近更新 更多