Обновление AppSettings через ASP.NET MVC Controller
Я пишу базовое небольшое веб-приложение для форумов (для удовольствия и для резки оле), и у меня проблемы с 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, поэтому пользователь процесса - это тот, кто имеет право собственности на файл в любом случае).
Любые идеи?
Ответы
Ответ 1
Измените свою первую строку следующим образом:
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 как "путь", позволяет нам для загрузки корневой конфигурации, но не сохранить ее.
Ответ 2
Попробуйте следующее:
var configFile = HttpContext.Current.Server.MapPath("~/Web.config");
var config = WebConfigurationManager.OpenWebConfiguration(configFile);
Однако, я думаю, что плохая идея хранить такую информацию в Web.Config, особенно если она предназначена для динамического изменения.
Даже если вы планируете использовать отдельный файл конфигурации, я предпочел бы хранить это по-другому, и я бы не стал получать свою собственную конфигурацию через классы System.Configuration. Они в основном предназначены для чтения приложений App.Config приложений Web.Config и приложений Windows для приложений ASP.NET и для их работы с чем-то другим, действительно бессмысленным.
Я рекомендую следующее:
Добавить отдельный XML файл в ваш проект. (желательно в папку App_Data, где он не может быть доступен из Интернета и где ваше приложение уже имеет права на чтение и запись.)
Затем вы можете сохранить этот тип настроек в этом XML и легко прочитать и записать его с помощью System.Xml или LINQ to XML.
Ответ 3
Если вы используете это из другого проекта, вы будете использовать конфигурацию из этой папки, у которой не будет файла конфигурации, поэтому ошибка, которую он не может создать.
Вы можете использовать server.mappath или что-то в этом роде для доступа к конфигурационному файлу веб-папок.