webentwicklung-frage-antwort-db.com.de

Wie OpenWebConfiguration mit physischem Pfad?

Ich habe ein Gewinnformular, das eine Site in IIS7 erstellt. Eine Funktion muss die Datei web.config öffnen und einige Aktualisierungen vornehmen. (Verbindungszeichenfolge, SMTP, Identitätswechsel)

Ich habe jedoch nicht den virtuellen Pfad, sondern nur den physischen Pfad.

Kann ich den WebConfigurationManager trotzdem verwenden?

Ich muss seine Fähigkeit verwenden, Abschnitt zu finden und zu lesen/schreiben.

System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration
31
aron

Sie müssen den PhysicalPath einem VirtualPath zuordnen. So würden Sie das machen.

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

Vadims Antwort hat auf unserem Dev-Server gut funktioniert, aber auf unserem Live-Server mit der folgenden Nachricht bombardiert:

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. Parameter name: site 

Um dies zu korrigieren, fand ich eine weitere Überladung für WebConfigurationManager.OpenMappedWebConfiguration, die den Websitenamen IIS als dritten Parameter verwendet. Das Ergebnis ist wie folgt:

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

Aufbauend auf der Antwort von Vadim fand ich heraus, dass das, was er schrieb, nicht genau für meine Situation funktionierte. Daher verwendete ich stattdessen Folgendes:

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

Falls irgendjemand anderes versucht, was ich versuche und das hier findet, bestand der Zweck meines Tuns darin, SimpleMembershipProvider, das von ExtendedMembershipProvider erbt, mit SQLite zu arbeiten. Dazu habe ich die Tabellen manuell über diesen Link erstellt: SimpleMembershipProvider in MVC4 und dann diesen Befehl in der Global.asax-Routine meiner Application_Start-Datei verwendet:

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

Es stellte sich heraus, dass ich meine web.config-Datei überhaupt nicht neu schreiben musste. (Es gab auch eine Menge Änderungen an web.config, die ich machen musste, aber das ist umso mehr, als diese Frage ausmacht.)

0
cjbarth

Vadims Antwort war genau das, was ich brauchte, aber ich stieß auf das gleiche Problem wie Kieth, und seine Lösung hat den Trick!

Ich dachte, ich würde hinzufügen, dass der IIS Website-Name durch Aufruf von abgerufen werden kann:

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

Der Code von cjbarth enthielt auch eine aufgeräumte Lösung für Tests in Umgebungen, in denen der Speicherort von wwwroot und Web.config variieren kann:

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

Vor diesem Hintergrund würde eine weitere geringfügige Verbesserung der Funktion von Vadim lauten:

    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
Fehr