通过ASP.NET MVC控制器更新AppSettings

14

我正在编写一个基础的小型论坛Web应用程序(出于兴趣和锻炼技巧),但在AppSettings方面遇到了一些问题。

我的计划是将这些设置存储在自己的文件(Settings.config)中,授予Web进程用户帐户修改权限,并在该文件中存储所有可编辑的设置(例如论坛标题、描述等)。

以下是我的代码:

[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个回答

21

把你的第一行改为这样:

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 为“路径”允许我们加载根配置但无法保存它的原因。


这实际上是一个非常有趣的行为,我之前没有听说过。非常感谢您的解释,因为我也有点不知所措。 - Venemo
谢谢,这非常有趣 - 我今晚会试一下! - Keith Williams
非常感谢。如果我们想将配置保存到另一个文件,比如app.config,该怎么办? - Ashkan Mobayen Khiabani

1

试试这个:

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

然而,我认为将此类信息存储在Web.Config中是一个不好的主意,尤其是如果它打算动态更改。

即使您计划使用单独的配置文件,我也宁愿以另一种方式存储此信息,而且我不想通过System.Configuration的类来获取自己的配置。它们大多用于读取ASP.NET应用程序的Web.Config和Windows应用程序的App.Config,并使它们与其他内容配合工作实际上是没有意义的。

我建议以下操作:

向项目添加一个单独的XML文件。(最好是添加到App_Data文件夹中,这样无法从网络访问,且您的应用程序已经具有读写权限。)

然后,您可以在该XML中存储此类设置,并轻松地使用System.Xml或LINQ to XML进行读取和写入。


是的,我知道这可能不是最好的方法 - 我只是想看看它是否有效,并尝试一些不同的东西(如果说实话,我太懒了,不想在我的数据库中设置一个设置表 ;) ) - Keith Williams
1
@Venemo - 你的建议非常有道理。使用XML文件更加实用,我们可以自由读写,而不受web.config所限制。我也喜欢将其放置在AppData中,因为读写权限已经被授予。更不用说它可以被无数个应用程序共享了。虽然我不会走得那么远 :) - Ben Junior

0
如果您正在从另一个项目运行此程序,那么您将使用该文件夹的配置,该配置文件不存在,因此会出现无法创建的错误。
您可能需要使用 server.mappath 或类似的方法来获取到 Web 文件夹中的配置文件。

你能澄清一下你所说的“从另一个项目中运行”是什么意思吗? - Keith Williams
如果您有自己的网站和业务层,则代码运行在业务层项目中,那么我怀疑它正在寻找的配置文件将在业务层项目中。您需要获取Web配置文件的路径。 - griegs
啊,我明白了...实际上不是这样的,虽然通常我会像那样设置,但在这种情况下,我有些懒惰,把业务层放在我的MVC应用程序的“Models”文件夹中。 - Keith Williams
@griegs: 这不是真的。System.Configuration从实际的AppDomain配置文件中读取配置。因此,即使业务层位于不同的项目或不同的DLL中,如果您从应用程序调用它,它仍将使用您的应用程序配置。 - Venemo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接