应用程序设置应该存储在哪里?

8

最近,我发现"Web.Config"文件包含一个<appSettings>部分,似乎很适合存储应用程序设置。它甚至有一种通过标准系统库访问该文件的编程方式。所以我聪明地写了一个接口来访问它,然后是一个实现该接口的具体实现,如下所示:

public interface IAppSettings
{
    IEnumerable<string> GetValues(string componentName, string settingName);
    IEnumerable<KeyValuePair<string, string>> GetValuePairs(string componentName, string settingName);
    void SetValues(string componentName, string settingName, IEnumerable<string> valueList, bool append);
    void SetValuePairs(string componentName, string settingName, IEnumerable<KeyValuePair<string, string>> pairList, bool append);
}

我发现在应用程序运行时将设置保存回“web.config”会导致整个应用程序重新启动,这对我来说完全不合理,因为如果我经常写回web.config并且每次应用程序重启,那么像HttpRuntime.Cache这样的东西就会被彻底清空,使我的缓存无效,因为它不断地清空和重新填充。

所以我想知道:我应该把我的应用程序设置存储在哪里?

是否有一个好的解决方案,这样我就不必自己开发?

编辑:

好的,感谢所有建议使用数据库和潜在表模式的人。我想我会采用以下模式:

settings:
    index NUMBER NOT NULL AUTO_INCREMENT   <== Primary Key
    component NVARCHAR(255) NOT NULL
    setting NVARCHAR(255) NOT NULL
    key   NVARCHAR(255)
    value NVARCHAR(255) NOT NULL

虽然我不认为我会将“设置”为P键,而是使用自动递增索引。这样,如果我有一个需要向多个经理发送邮件的应用程序,我可以存储许多内容。
index     component       setting        value
1         RequestModule   ManagerEmail   manager1@someplace
2         RequestModule   ManagerEmail   manager2@someplace

然后我可以使用:

IEnumerable<string> GetValues(string componentName, string settingName);

它将返回一个电子邮件地址列表,而不仅仅是单个值。

这样说清楚了吗?


2
使用数据库存储应用程序设置是可以的,但请将设置存储在缓存中。Web.config 中的设置读取速度很快,因为它们位于服务器内存中。如果您在每个页面上不断读取设置,请考虑将缓存添加到您的设置中,并在更新设置时从缓存中删除它们。 - Carlos Muñoz
根据您的编辑,我修改了我的答案。请注意,当您有两个问题时,请分别提出,而不是将第二个问题添加到前一个问题中。 - Arseni Mourzenko
9个回答

14

web.config一般用于只读设置,即由系统管理员在应用程序部署期间设置的设置。

如果想要读取编写设置,则最明显的方法是使用数据库。顺便说一句,这有一个优点:一个应用程序可以托管在多个服务器上,并仍然正确地读取和编写设置。

您还可以为设置实现自定义存储,但这可能更难实现且不会更快。


回答您的第二个问题,您的数据库结构取决于您要存储的设置类型。

如果需要存储类似于以下内容的异构唯一条目

  • 管理员的邮件地址,
  • 网站主页上显示的最大条目数,
  • "关于我们"页面上显示的文本,
  • 指示是否启用公共评论的布尔值,

那么您必须使用varchar或其他更或多或少友好的类型作为键来标识条目(而不是通过它们的索引引用它们)。

另一方面,如果您的目的是存储多个管理者的电子邮件地址,则应创建一个Manager表,其中包含他们的电子邮件地址、姓名、最后连接时间等。

您真的不应该混合使用两者。理论上,您可以按组件/设置对引用设置的条目。实际上,这会使事情变得更加困难,并创建一堆问题:

  • 如果将来每个管理器都需要存储一个布尔值,表示他/她是否想收到您的警报怎么办?在当前结构下,这将是不可能的。
  • 由于同一设置可能具有多个值,因此您打算如何处理必须是唯一的设置?例如,“关于我们”页面上显示的文本只能有一个值。如果数据库中存储了两个值,该怎么办?

有趣的是,我从未考虑过应用程序可能在多个服务器上运行,但这很有道理。对于我的情况来说,这很可能永远不会发生,因为它是一个内部公司项目,但这值得记住。 - Pretzel
有趣。我刚刚在搜索如何存储单个值,因为启动只包含一个记录、一个整数的数据库表感觉不对。但你说“web.config通常用于只读设置”也很有道理。由于你(优秀)的回答,我现在对在Web服务中存储应用程序范围的读/写整数的最佳位置感到困惑。 - dumbledad

6

将设置存储在web.config中非常有用,因为它使得在不同的环境中拥有不同的设置变得容易。然而,正如你所说,如果你想要在现场环境中更改设置,则这没有任何用处。

如果需要更改值,则简单的数据库表是最有用的方法。

例如:

create table Settings
(Name varchar(50) primary key,
Value varchar(50))

如果你正在使用SQL Server,你可以将Value列设置为sql_variant,这将允许你存储各种数据类型。


2
+1 for sql_variant. 当存储任何类型的数据时(更不用说varchar(100)),使用nvarchar(max)并不是一个好主意。 - Arseni Mourzenko

5

是的。更改web.config将重置应用程序。我通常维护一个设置表来存储键值对以供设置,并从那里访问它。

设置

SETTING_NAME   VARCHAR(100)PRIMARY KEY
SETTING_VALUE  VARCHAR(100)

接下来编写一个类,可以向该表中插入、删除和更新值。

SETTINGS表的示例数据:

    SETTING_NAME         SETTING_VALUE

    AdminEmail            admin@mysite.com
    ErrorTrackingEmail    errors@mysite.com

name 应该是主键。分离的列没有意义。 - abatishchev

5

这个设置是用于应用程序设置,而不是在运行时动态更改的设置。相反,它适用于仅偶尔更改的设置,并且当更改时您希望(甚至期望)应用程序重新启动。

对于更短暂的设置,您可能只需使用简单的数据库系统 - 即使是位于App_Data目录中的平面文件/XML也可以使用,如果您的应用程序没有使用其他数据库。


3

我通常会在我的设置表中添加一个“类型”字段,以便只检索所需的设置组,这对于我来说是一种将类似设置分组并一次性检索它们的方法。


在哪种情况下需要获取一组设置?主要是出于性能原因吗? - Karl Glennon
一些设置被分组,例如DirectoryPath,如果我正在寻找DirectoryPath,我只需提取所有类型为DirectoryPath的设置,然后遍历它们即可。 - jangeador

1
创建一个像这样的键值表:
settings:
name NVARCHAR(255) PRIMARY KEY
value NVARCHAR(255) NOT NULL

1

首先,考虑到 web.config 文件中应存储的信息,这并不是不合理的。当您更改程序集信息、连接字符串等内容时,您的应用程序需要停止并重新加载值以使用这些设置。

如果您要存储应用程序范围内的设置,则可以在数据库中创建一个设置表,甚至可以使用单独的文本文件来存储设置。

如果您要存储每个用户的设置,则应查看 ASP.NET Profile Properties


“不合理”是指应用程序的不断“重新启动”会产生性能问题,而我无法容忍这种副作用。(并不是说重新启动的原因不合理...)--感谢您指出ASP.NET配置文件属性。虽然它不完全符合我的要求,但我认为它将有助于解决我遇到的另一个问题... :-) - Pretzel

1

应用程序范围的设置应该存储在web.config文件的这个部分中,以防止硬编码可能随时间变化的值。无需使用自己的代码读取它们,因为有一个内置方法:使用System.Configuration.ConfigurationManager.AppSettings数组来检索它们(您需要在项目中添加对System.Configuration程序集的引用)。您还可以通过ASP.NET网站管理工具编辑AppSettings(项目菜单 -> ASP.NET配置)。

对于您预计在站点运行时更频繁更改的值,可以合理地使用XML文件、轻量级数据库(如SQLite或SQL Server Compact)甚至文本文件来存储这些设置。


0
如果您需要保存设置,您可以随时将它们保存在自定义配置文件中。
我之前就是这样做的,并且现在可以在 这里 找到相关代码。

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