Обновление AppSettings через ASP.NET MVC Controller - PullRequest
11 голосов
/ 17 ноября 2009

Я пишу простенькое веб-приложение для форумов (для развлечения и оттачивания ole 'saw), и у меня возникли небольшие проблемы с AppSettings.

Мой план состоит в том, чтобы эти настройки были в их собственном файле (Settings.config), которому я предоставлю права на изменение учетной записи пользователя веб-процесса, и сохраню все редактируемые настройки в этом файле (например, заголовок форума, описание и т. Д.). ).

Это мой код:

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

... но при его запуске возвращается следующая ошибка:

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

Я попытался предоставить всем пользователям полное разрешение на доступ к файлу настроек, но безрезультатно (в настоящее время я работаю под Cassini, так что пользователь процесса - это я, который в любом случае владеет файлом).

Есть идеи?

Ответы [ 3 ]

19 голосов
/ 22 ноября 2009

Измените свою первую строку на это:

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

Как ни странно, OpenWebConfiguration ожидает виртуальный путь к файлу Web.config, исключая имя файла. Я предполагаю, что логика в том, что в любом каталоге будет только один Web.config, поэтому указывать имя не нужно.

Документация MSDN в конечном счете подсказывает нам здесь - если вы посмотрите на примеры, все они используют явные относительные пути, а при размещении в IIS позволяют вам указывать файлы конфигурации из других мест, например:

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

Добавление:

Так почему же OpenWebConfiguration("~/Web.config") вообще работает? Я не уверен, что могу точно объяснить это, но попробуйте это для пинки: измените его на ("~ / Foo.bar") . Тот же результат! Вы можете прочитать - ваш же файл Web.config - но не можете написать! (теперь попробуйте добавить каталог foo.bar на ваш сайт, затем поместите в него файл Web.config ...)

Поскольку OpenWebConfiguration ожидает каталог (и, по-видимому, допускает несуществующие, если он находит Web.config в родительском), я думаю, что именно поэтому ошибочное указание ~ / Web.config в качестве «пути» позволяет нам загрузить корневой конфиг, но не сохранить его.

1 голос
/ 22 ноября 2009

Попробуйте это:

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

Однако я считаю плохой идеей хранить такую ​​информацию в Web.Config, особенно если она предназначена для динамического изменения.

Даже если вы планируете использовать отдельный файл конфигурации, я бы предпочел сохранить его по-другому, и я бы не стал получать свою собственную конфигурацию через классы System.Configuration. В основном они предназначены для чтения приложений App.Config приложений ASP.NET и приложений Windows.Config, и заставить их работать с чем-то другим действительно бессмысленно.

Я рекомендую следующее:

Добавьте отдельный файл XML в ваш проект. (предпочтительно в папку App_Data, где к ней нельзя получить доступ из Интернета и где у вашего приложения уже есть разрешения на чтение и запись.)

Затем вы можете сохранить настройки такого типа в этом XML и легко читать и записывать их, используя System.Xml или LINQ to XML.

0 голосов
/ 17 ноября 2009

Если вы запускаете это из другого проекта, то вы будете использовать конфигурацию из этой папки, у которой не будет файла конфигурации, следовательно, ошибка, что он не может быть создан.

Возможно, вы захотите использовать server.mappath или что-то подобное для доступа к файлу конфигурации веб-папок.

...