Как открыть конфигурацию с физическим путем? - PullRequest
32 голосов
/ 03 марта 2010

У меня есть выигрышная форма, которая создает сайт в IIS7. Одна функция должна открыть файл web.config и сделать несколько обновлений. (строка подключения, smtp, олицетворение)

Однако у меня нет виртуального пути, только физический путь.

Можно ли как-нибудь использовать WebConfigurationManager?

Мне нужно использовать его способность находить раздел и читать / писать.

System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration

Ответы [ 4 ]

63 голосов
/ 18 марта 2010

Вы должны будете сопоставить физический путь с виртуальным путем. Вот как бы вы это сделали.

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, "/");
}
10 голосов
/ 12 октября 2012

Ответ Вадима отлично сработал на нашем сервере разработки, но сработал на нашем живом сервере со следующим сообщением:

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");
}
0 голосов
/ 20 июля 2016

Вадим ответил именно то, что мне было нужно, но я столкнулся с той же проблемой, что и Киет, и его решение помогло!

Я решил добавить, что имя веб-сайта IIS можно получить, позвонив по номеру :

System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();

Кроме того, код cjbarth включал в себя удобное решение для тестирования в средах, где расположение wwwroot и Web.config может варьироваться:

System.Web.HttpContext.Current.Server.MapPath("~");

Таким образом, с учетом этого еще одно небольшое улучшение функции Вадима будет выглядеть так:

    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);
    }
0 голосов
/ 23 января 2013

Опираясь на ответ Вадима, я обнаружил, что написанное им не совсем подходит для моей ситуации, поэтому я использовал это вместо:

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 в MVC4 , а затем использовал эту команду в моей Global.asax подпрограмме Application_Start файла:

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

Что, оказывается, не требовало от меня переписывания файла web.config вообще. (Мне также пришлось внести много изменений в web.config, но это еще больше выходит за рамки этого вопроса.)

...