2009-11-16 15 views
10

Ich schreibe eine grundlegende kleine Foren-Web-App (zum Spaß und um die ole 'Säge zu schärfen), und ich habe ein bisschen Probleme mit AppSettings.Aktualisieren von AppSettings über ASP.NET MVC Controller

Mein Plan ist, diese Einstellungen in einer eigenen Datei (Settings.config) zu haben, der ich dem Benutzerkonto des Webprozesses Änderungsberechtigungen erteilen und alle bearbeitbaren Einstellungen in dieser Datei speichern werde (zB Forumtitel, Beschreibung, etc).

Dies ist mein Code:

 
[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(FormCollection collection) 
{ 
    try 
    { 
     var config = WebConfigurationManager.OpenWebConfiguration("~/Web.config"); 

     config.AppSettings.Settings["SiteTitle"].Value = collection["SiteTitle"]; 
     config.AppSettings.Settings["SiteDescription"].Value = collection["SiteDescription"]; 

     config.Save(ConfigurationSaveMode.Minimal, false); 
     ConfigurationManager.RefreshSection("appSettings"); 

     return RedirectToAction("Index"); 
    } 
    catch (Exception ex) 
    { 
     ModelState.AddModelError("_FORM", ex.Message); 
     return View("Index"); 
    } 
} 

... aber läuft es den folgenden Fehler zurückgibt:

A configuration file cannot be created for the requested Configuration object.

ich die volle Berechtigung für alle Benutzer auf die Einstellungsdatei versucht haben, die Gewährung von , ohne Wirkung (ich laufe gerade unter Cassini, also bin ich der Prozessbenutzer, der in jedem Fall Eigentümer der Datei ist).

Irgendwelche Ideen?

Antwort

18

Ändern Sie Ihre erste Zeile dazu:

var config = WebConfigurationManager.OpenWebConfiguration("~"); 

Verwirrend, wie es sein kann, erwartet OpenWebConfiguration der virtuelle Pfad, in dem die Web.config, ohne der Dateiname befindet. Ich denke, die Logik ist, dass es nur ein Web.config in einem bestimmten Verzeichnis geben wird, so dass der Name unnötig ist.

Die MSDN documentation letztlich Hinweise uns hier in - wenn Sie die Beispiele sehen sie alle verwenden explizite relative Pfade, und wenn sie unter IIS-Hosting können Sie Konfigurationsdateien von anderen Orten, zum Beispiel angeben:

OpenWebConfiguration("/siteName", "Default Web Site", null, "myServer"); 

Zusatz:

Also warum funktioniert OpenWebConfiguration("~/Web.config") überhaupt? Ich bin mir nicht sicher, ob ich es definitiv erklären kann, aber probiere das aus, um es zu ändern: ändere es in ("~/Foo.bar"). Das gleiche Ergebnis! Sie können lesen - Ihre gleiche Web.config-Datei - aber kann nicht schreiben! (Versuchen Sie jetzt, das Verzeichnis foo.bar zu Ihrer Site hinzuzufügen, und fügen Sie dann eine Web.config ein ...)

Da OpenWebConfiguration ein Verzeichnis erwartet (und anscheinend nicht existierende erlaubt, solange es ein Web findet) .config innerhalb des Parents). Ich glaube, das ist der Grund, warum wir versehentlich ~/Web.config als "Pfad" angeben, um die Root-Konfiguration zu laden, aber nicht zu speichern.

+0

Das ist eigentlich ein sehr interessantes Verhalten, von dem ich noch nichts gehört habe. Vielen Dank für die Erklärung, da ich auch ein wenig ahnungslos war. – Venemo

+0

Danke, das ist sehr interessant - ich werde es heute Abend versuchen! –

+1

Arbeitete wie ein Zauber - danke! –

0

Wenn Sie dies von einem anderen Projekt ausführen, dann verwenden Sie die Konfiguration aus diesem Ordner, die keine Konfigurationsdatei hat, daher der Fehler, dass sie nicht erstellt werden kann.

Sie können server.mappath oder etwas ähnliches verwenden, um zur Konfigurationsdatei der Webordner zu gelangen.

+0

Könnten Sie klarstellen, was Sie meinen, indem Sie "von einem anderen Projekt ausführen"? –

+0

Wenn Sie Ihre Website haben und Sie Ihre Business-Schicht haben, und der Code im Business-Schicht-Projekt ausgeführt wird, dann vermute ich, dass die gesuchte Konfigurationsdatei im Business-Schicht-Projekt sein wird. Sie müssen den Pfad zur Web-Konfigurationsdatei – griegs

+0

Ah, ich sehe ... eigentlich nicht, während ich normalerweise Dinge so einrichten, in diesem Fall bin ich faul und haben die Business-Schicht im Ordner "Modelle" meiner MVC-App. –

1

Versuchen Sie folgendes:

var configFile = HttpContext.Current.Server.MapPath("~/Web.config"); 
var config = WebConfigurationManager.OpenWebConfiguration(configFile); 

Aber ich denke, es ist eine schlechte Idee ist, diese Art von Informationen in der Web.Config zu speichern, vor allem, wenn es beabsichtigt ist, dynamisch geändert werden.

Auch wenn Sie eine separate Konfigurationsdatei verwenden möchten, würde ich dies lieber auf eine andere Weise speichern, und ich würde nicht die Mühe haben, meine eigene Konfiguration durch die Klassen von System.Configuration zu bekommen. Sie sind hauptsächlich dazu gedacht, die App.Config der Web.Config- und Windows-Apps von ASP.NET-Apps zu lesen und sie mit etwas anderem arbeiten zu lassen, ist wirklich sinnlos.

Ich empfehle die folgenden:

In einer separaten XML-Datei in Ihrem Projekt. (Vorzugsweise auf den Ordner App_Data, wo sie nicht aus dem Internet zugegriffen werden kann, und wo Ihre Anwendung bereits Lese- und Schreibrechte.)

Sie können dann speichern Sie diese Art von Einstellungen in diesem XML und leicht zu lesen und schreibe es mit System.Xml oder LINQ to XML.

+0

Ja, ich weiß, dass es nicht der beste Weg ist, dies zu tun - ich wollte nur sehen, ob es funktioniert und etwas anderes ausprobieren (und war zu faul, um eine Einstellungstabelle in meiner Datenbank einzurichten, wenn ich es bin ehrlich;)) –

+1

@Venemo - Ihr Vorschlag macht viel Sinn. Es ist viel praktischer, eine XML-Datei zu verwenden, in der wir ohne die Einschränkungen von web.config frei lesen und schreiben können. Ich mochte auch den Vorschlag, es in den AppData zu platzieren, wo die Lese- und Schreibrechte bereits vergeben sind. Nicht zu erwähnen, dass es von unzähligen Apps geteilt werden kann. Nicht, dass ich so weit gehen werde :) –

+0

@BenJunior - danke :) Ich bin froh, dass ich helfen konnte! – Venemo