.NET:当所需的configuration设置丢失时抛出哪个exception?

这是一个标准的scheme:

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

问题是,我不完全确定哪个exceptionSomeStandardException应该是。

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

System.Configuration.ConfigurationException

发生configuration系统错误时引发的exception。

备注

如果应用程序尝试读取或写入数据到configuration文件但不成功,则抛出ConfigurationExceptionexception。 一些可能的原因可能包括configuration文件中格式不正确的XML,文件权限问题以及包含无效值的configuration属性。

注意:

ConfigurationException对象是为了向后兼容而维护的。 ConfigurationErrorsException对象将其replace为configuration系统。

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

这让我们非常困惑的ConfigurationErrorsException

System.Configuration.ConfigurationErrorsException

当前值不是EnableSessionState值之一。

正如你所看到的,它的文档是完全没有用的。 (在本地和在线帮助中都是这样的)。对class级本身的考察表明,对于我想要的,这是一种激烈的矫枉过正。

简而言之,我需要一个标准的exception,当应用程序configuration设置丢失或者包含一个无效的值时应该抛出exception。 你会认为框架有这样一个例外,它的应用程序使用。 (它显然是这样做的,但它已经被标记为过时了,被范围上更大的东西所取代)。

有什么解决scheme,如果有的话,你们用这个,我将不得不把它吸了,并为此滚动我自己的例外?

编辑附录

有人问我是否可以提供默认值,并继续。 在某些情况下,是的,在这种情况下,这个例外不会被抛出。 但是,对于某些设置,这不适用。 例如:数据库服务器名称和凭据,身份validation服务器以及安装的第三方应用程序的path。

还值得注意的是,我主要处理的应用程序是一个控制台应用程序在批处理模式下运行,我希望它引发一个由主要方法捕获的exception,如果没有适当的configuration适当的日志logging。 (这是我inheritance的遗留代码,目前只是假设一切都很好)。

您不受限于您的exception – 在框架中抛出现有的exception。 如果您决定使用现有的例外情况,则您不一定必须遵循该文件的信函。 该文档将描述框架如何使用给定的exception,但并不意味着对如何select使用/重用现有exception的限制。

这是您的应用程序 – 只要您logging它,并清楚地指出将在缺lessconfiguration值的特定情况下抛出的exception,则可以使用您喜欢的任何exception。 如果你想要一个非常具体的缺失值的指示,你可以考虑编写你自己的ConfigurationSettingMissingexception:

 [Serializable] public class ConfigurationMissingException : ConfigurationErrorsException {} 

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

更新:我同意的意见,所以我已经从exception改变了ConfigurationErrorsException的子类。 我认为在可能的情况下从现有的Frameworkexception中inheritance自定义exception是一个好主意,避免了Exception类,除非需要特定于应用程序的exception。

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

对我来说,configurationexception(和它的替代,ConfigurationErrorsException – 尽pipe误导MSDN文档)是保存,阅读等configuration错误。

正如Daniel Richardson所说, ConfigurationErrorsException是一个可以使用的方法。 通常,只有build议您创build自己的自定义“exception”types(如果您有处理它们的场景)。 在通常致命的configuration错误的情况下,这种情况很less出现,因此重用现有的ConfigurationErrorsExceptiontypes通常更合适。

在.NET 2.0之前,build议使用System.Configuration.ConfigurationException 。 ConfigurationException在.NET 2.0中变得过时了,原因是我从来不清楚,并且build议更改为使用ConfigurationErrorsException。

我使用助手方法来引发exception,以便在从.NET 1.x迁移到2.0时,或者如果Microsoft决定再次更改build议,可以很容易地更改抛出的exception:

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

那么System.Configuration.SettingsPropertyNotFoundException呢?

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

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

较早的MSDN总结和评论是:

  • 发生configuration系统错误时引发的exception。
  • 当正在读取或写入configuration信息时发生任何错误时,将引发ConfigurationErrorsExceptionexception。

ConfigurationElement类(它是许多configuration相关类的基类,如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)); } 

我会吮吸它,然后推出自己的…但在此之前,是否可以让系统为此configuration设置假定默认值? 我通常会尝试这样做,因为每一个可能会被忽略的设置都可能会被忽略。(或者我应该说,尽可能多的设置 – 对于一些人来说,显然不适合让系统做出默认决定。 ..)

一般来说,一个自定义的exception并不是很多的努力…这里是一个例子…

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

你可以使用你的configuration文件的另一种方法是使用自定义configuration部分,而不是AppSettings 。 这样你可以指定一个属性IsRequired ,configuration系统将为你处理这个检查。 如果该属性丢失,则会抛出ConfigurationErrorsException所以我认为支持你应该在你的情况下使用该exception的答案。

我的一般规则是:

  1. 如果缺lessconfiguration的情况不是很常见,我相信我绝对不会想要处理这种情况比其他exception,我只是使用基本的“例外”类与适当的消息:

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

  2. 如果我确实需要,或者认为我想要以不同于大多数其他例外的方式来处理这种情况的概率很高,那么我会按照人们已经在这里build议的方式推出我自己的types。

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

简而言之,我需要一个标准的exception,当应用程序configuration设置丢失或者包含一个无效的值时应该抛出exception。 你会认为框架有这样一个例外,它的应用程序使用。 (它显然是这样做的,但它已经被标记为过时了,被范围上更大的东西所取代)。

根据关于System.Exception( Exception Class)的MSDN文档,出于性能方面的考虑,你不应该为用户input错误抛出exception(Stack Overflow和其他人已经指出了这一点),这似乎是有道理的那么 – 为什么你的函数不能返回false,如果用户inputinput不正确,然后让应用程序正常退出?这似乎是更多的devise问题,然后抛出exception的问题。

正如其他人所指出的那样,如果您确实必须抛出exception – 无论出于何种原因 – 没有任何理由不能通过inheritanceSystem.Exception来定义Exceptiontypes。

您可以尝试inheritanceXMLexception,或者只是使用它。