. NET: 当所需配置设置丢失时引发哪个异常?

下面是一个标准的场景:

if(string.IsNullOrEmpty(Configuration.AppSettings["foobar"]))
throw new SomeStandardException("Application not configured correctly, bozo.");

问题是,我不完全肯定 哪个异常 SomeStandardException应该是。

我仔细阅读了3.5框架,发现了两个可能的候选框架: ConfigurationExceptionConfigurationErrorsException

系统。配置。配置异常

时引发的异常 配置系统错误 发生了。

备注

ConfigurationException异常是 如果应用程序试图 读取或写入数据到 配置文件,但是 一些可能的原因 中包含格式不正确的 XML 配置文件 权限问题和配置 属性的值不是 有效。

注:

ConfigurationException对象是 向下兼容。 ConfigurationErrorsException 对象将其替换为 配置系统。

这个异常听起来非常适合我的需要,但它已经被标记为过时了,所以,不要再提了。

这就把我们带到了完全令人费解的 ConfigurationErrorsException:

System.ConfigurationErrorsException

当前值不是 EnableSessionState 值。

如您所见,它的文档完全没用。(在本地和在线帮助中都是这样。)对这门课本身的检查表明,它对于我想要的东西来说过于夸张了。

简而言之,我需要一个标准异常,当应用程序配置设置丢失或包含无效值时,应该引发该异常。您可能会认为框架中包含了这样一个异常,以供应用程序使用。(显然是这样的,但它被标记为过时的,并被范围更大的 很多所取代。)

如果有的话,你们有什么解决方案吗? 我是不是应该忍耐一下,然后为这个问题卷起我自己的异常?

编辑附录

有些人问我是否可以提供一个默认值,然后继续。在某些情况下,是的,在这些情况下,不会引发异常。但是,对于某些设置,这不适用。例如: 数据库服务器名称和凭据、身份验证服务器以及安装的第三方应用程序的路径。

同样值得注意的是,我主要处理的应用程序是一个在批处理模式下运行的控制台应用,我希望它抛出一个由 main 方法捕获的异常,如果没有正确配置该异常,它会被正确地记录。(这是我继承的遗留代码,目前只有 假设,一切都很好。)

51750 次浏览

我会忍气吞声,然后卷起我自己的... 但是在你这么做之前,有没有可能让系统为这个配置设置假设一个默认值?我通常尝试为每一个设置,可能会错过运营管理人员... (或者也许我应该说,为尽可能多的设置-对一些人来说,这显然是不合适的系统作出一个默认的决定...)

一般来说,自定义异常并不需要很多努力... ... 这里有一个例子... ..。

[Serializable]
public class MyCustomApplicationException : ApplicationException
{
#region privates
#endregion privates


#region properties
#endregion properties


public MyCustomApplicationException (string sMessage,
Exception innerException)
: base(sMessage, innerException) { }
public MyCustomApplicationException (string sMessage)
: base(sMessage) { }
public MyCustomApplicationException () { }


#region Serializeable Code
public MyCustomApplicationException (
SerializationInfo info, StreamingContext context)
: base(info, context) { }
#endregion Serializeable Code
}

您可以尝试继承 XML 异常,或者仅仅使用它。

抛出异常并不局限于框架中现有的异常。如果您确实决定使用现有的异常,则不一定非要严格遵循文档。文档将描述 框架如何使用给定的异常,但是对于 如何选择使用/重用现有的异常没有任何限制。

它是您的应用程序——只要您对它编写文档,并清楚地指出在缺少配置值的特定情况下将抛出的异常,您就可以使用任何您喜欢的异常。如果您确实需要非常具体的 失踪了值指示,您可以考虑编写自己的 ConfigurationSettingLost 异常:

[Serializable]
public class ConfigurationMissingException : ConfigurationErrorsException
{}

编辑: 在这种情况下编写您自己的异常可以带来额外的好处,保证在异常来自框架或您的应用程序方面永远不会有任何混淆。框架永远不会抛出自定义异常。

更新: 我同意这些注释,所以我将子类从 Exception 更改为 ConfigurationErrorsException。我认为从现有 Framework 异常中继承自定义异常通常是一个好主意,除非需要特定于应用程序的异常,否则避免使用 Exception 类。

就个人而言,我会使用 InvalidOperationException,因为它是对象状态的问题,而不是配置系统的问题。毕竟,您不应该允许这些设置由代码设置而不是配置吗?这里重要的部分不是 app.config 中没有行,而是不存在所需的信息。

对我来说,ConfigurationException (以及它的替代,ConfigurationErrorsException ——尽管有误导性的 MSDN 文档)是用于保存、读取等 Configuration 中的错误。

ConfigurationElement 类(它是许多与配置相关的类(如 ConfigurationSection)的基类)有一个名为 OnRequredPropertyNotfound 的方法(也有其他的帮助器方法)。你可以称之为。

OnRequredPropertyNotfound 是这样实现的:

protected virtual object OnRequiredPropertyNotFound(string name) {
throw new ConfigurationErrorsException(SR.GetString("Config_base_required_attribute_missing", new object[] { name }), this.PropertyFileName(name), this.PropertyLineNumber(name)); }

我的一般原则是:

  1. 如果缺少配置的情况并不常见,而且我相信我永远不会想用不同于其他异常的方式来处理这种情况,那么我只需要使用基本的“ Exception”类和适当的消息:

    抛出新的 Exception (“ my message here”)

  2. 如果我确实想要,或者认为很有可能我想要以一种不同于大多数其他例外的方式来处理这个案例,我会按照人们已经在这里提出的建议,推出我自己的类型。

我不同意你问题的前提:

简而言之,我需要一个标准异常,当应用程序配置设置丢失或包含无效值时,应该引发该异常。您可能会认为框架中包含了这样一个异常,以供应用程序使用。(它显然是这样做的,但它被标记为过时的,并被更大范围的东西所取代。)

根据系统上的 MSDN 文档。异常(例外类别,出于性能原因(Stack Overflow 和其他地方的人已经指出) ,您确实不应该为用户输入错误抛出异常。这似乎也有道理——如果用户输入不正确,为什么函数不能返回 false,然后应用程序优雅地退出?这似乎更像是一个设计问题,而不是引发 Exception 的问题。

正如其他人指出的那样,如果真的 抛出异常——不管出于什么原因——那么没有任何理由说明为什么不能通过从 System 继承来定义您的 Exception 类型。例外。

ConfigurationErrorsException是一个正确的例外,可以放入您所描述的情况中。ConfigurationErrorsException的 MSDN 文档的早期版本更有意义。

Http://msdn.microsoft.com/en-us/library/system.configuration.configurationerrorsexception(vs.80).aspx

早些时候的 MSDN 摘要和评论如下:

  • 时引发的异常 配置-系统错误 发生了。
  • ConfigurationErrorsException 当出现任何错误时引发异常 在配置时发生 信息正在被阅读或 写好了。

正如 Daniel Richardson 所说,配置错误异常是可以使用的。一般来说,只有在您有场景来处理自定义 Exception 类型时,才建议您创建自定义 Exception 类型。在配置错误(通常是致命的)的情况下,这种情况很少发生,因此通常更适合重用现有的 ConfigurationErrorsException 类型。

之前。NET 2.0,建议使用 系统。配置。配置异常。中的配置异常过时。NET 2.0,原因我一直不清楚,建议改为使用 ConfigurationErrorsException。

我使用一个 helper 方法来抛出异常,这样在从。NET 1.x 到2.0,或者如果微软决定再次改变建议:

if(string.IsNullOrEmpty(Configuration.AppSettings("foobar")))
{
throw CreateMissingSettingException("foobar");
}


...


private static Exception CreateMissingSettingException(string name)
{
return new ConfigurationErrorsException(
String.Format
(
CultureInfo.CurrentCulture,
Properties.Resources.MissingConfigSetting,
name
)
);
}

您可以使用配置文件的另一种方法是使用自定义配置节,而不是 AppSettings。这样,您可以指定属性 IsRequired和配置系统将为您处理这种检查。如果该属性丢失,它将抛出一个 ConfigurationErrorsException,所以我认为这支持您应该在您的情况下使用该异常的答案。