.NET:缺少必需的配置设置时抛出哪个异常?

时间:2009-01-06 16:23:17

标签: .net exception configuration

以下是标准方案:

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

问题是,我并不完全确定应该是异常SomeStandardException

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

  

System.Configuration.ConfigurationException

     

a时抛出的异常   配置系统错误了   发生。

     

备注

  ConfigurationException例外是   如果应用程序尝试,则抛出   读取或写入数据   配置文件但是   不成功。一些可能的原因   为此,可能包括格式错误的XML   配置文件,文件   权限问题和配置   值不是的属性   有效的。

     

注意:

     

ConfigurationException对象是   保持向后兼容性。   ConfigurationErrorsException   对象替换为   配置系统。

这个例外实际上对于我需要的东西来说听起来很完美,但它已被标记为过时,所以,ixnay on atthay。

这让我们彻底迷惑ConfigurationErrorsException

  

System.Configuration.ConfigurationErrorsException

     

当前值不是其中之一   EnableSessionState值。

如您所见,其文档完全没用。 (在本地和在线帮助中都是如此。)对课程本身的检查表明,对于我想要的东西来说,这是一种极端的过度杀伤力。

简而言之,我需要一个标准异常,当应用程序配置设置丢失或包含无效值时应抛出该异常。你认为框架有一个例外,它允许应用程序使用它。 (显然它确实如此,但它被标记为过时,并且被范围更大的 所取代。)

你们有什么解决方案,如果有的话,我会为此而努力,并为此推出自己的例外情况?

编辑附录

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

值得注意的是,我主要处理的应用程序是以批处理模式运行的控制台应用程序,我希望它抛出一个由main方法捕获的异常,如果事情不是适当配置。 (这是我继承的遗留代码,目前只是假设一切都很好。)

11 个答案:

答案 0 :(得分:41)

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

对我来说,ConfigurationException(以及它的替换,ConfigurationErrorsException - 尽管有误导性的MSDN文档)是出于配置的保存,读取等错误。

答案 1 :(得分:31)

您对例外投掷到框架中的现有异常不受限制。如果您决定使用现有的例外,则不必完全按照文档中的说明进行操作。该文档将描述框架如何使用给定的异常,但并不意味着选择使用/重用现有异常的方式有任何限制。

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

[Serializable]
public class ConfigurationMissingException : ConfigurationErrorsException
{}
编辑:在这种情况下编写自己的异常带来了额外的好处,即保证不会出现异常来自框架或应用程序的混淆。该框架永远不会抛出您的自定义异常。

更新:我同意这些评论,因此我已将子类更改为Exception中的ConfigurationErrorsException。我认为在可能的情况下从现有框架异常中继承自定义异常通常是一个好主意,避免使用异常类,除非您需要特定于应用程序的异常。

答案 2 :(得分:17)

正如Daniel Richardson所说, ConfigurationErrorsException 是要使用的。通常,只有在有方案来处理它们时,才建议您创建自己的自定义异常类型。对于通常致命的配置错误,很少会出现这种情况,因此通常更适合重用现有的ConfigurationErrorsException类型。

在.NET 2.0之前,建议使用 System.Configuration.ConfigurationException 。 ConfigurationException在.NET 2.0中已经过时,原因从来都不清楚,建议改为使用ConfigurationErrorsException。

我使用帮助器方法抛出异常,以便在从.NET 1.x迁移到2.0时,或者如果Microsoft决定再次更改建议时,很容易更改在一个地方抛出的异常:

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

答案 3 :(得分:15)

答案 4 :(得分:8)

ConfigurationErrorsException是抛出你描述的情况的正确例外。 ConfigurationErrorsException的早期版本的MSDN文档更有意义。

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

早期的MSDN摘要和备注是:

  • a时抛出的异常 配置系统错误有 发生。
  • ConfigurationErrorsException 任何错误都会抛出异常 配置时发生 信息正在阅读或 写入。

答案 5 :(得分:6)

ConfigurationElement类(许多与配置相关的类的基类,如ConfigurationSection)有一个名为OnRequiredPropertyNotFound的方法(还有其他辅助方法)。你可以打电话给那些。

OnRequiredPropertyNotFound的实现如下:

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

答案 6 :(得分:1)

我已经把它吸了起来并自己动手......但在你这样做之前,是否有可能让系统假定这个配置设置的默认值?我通常会尝试为Ops管理人员错过的每一个设置做到这一点......(或者我应该说,对于尽可能多的设置 - 对于某些人来说,让系统作出默认决定显然是不合适的。 ..)

一般来说,自定义异常不是很费力......这是一个例子......

[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
}

答案 7 :(得分:1)

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

答案 8 :(得分:0)

我的一般规则是:

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

    抛出新的异常(“我的消息在这里”)

  2. 如果我确实想要,或者认为很有可能我想以不同于大多数其他例外的方式处理这种情况,我会像人们已经在这里提出的那样推出自己的类型。

答案 9 :(得分:0)

我倾向于不同意你的问题的前提:

  

简而言之,我需要一个标准异常,当应用程序配置设置丢失或包含无效值时应抛出该异常。你认为框架有一个例外,它允许应用程序使用它。 (显然它确实如此,但它已被标记为过时,并被更大范围的东西取代。)

根据关于System.Exception(Exception Class的MSDN文档,出于性能原因(在Stack Overflow和其他地方的其他人已经指出),你真的不应该抛出用户输入错误的异常。这似乎也有意义 - 如果用户输入输入不正确,然后让应用程序正常退出,为什么你的函数不能返回false?这似乎更像是一个设计问题,然后抛出Exception的问题。

正如其他人所指出的,如果你真的抛出异常 - 无论出于什么原因 - 没有任何理由你不能通过继承System.Exception来定义你的异常类型

答案 10 :(得分:-2)

您可以尝试继承XML Exception,或者只是使用它。