这是一个标准方案:
if(string.IsNullOrEmpty(Configuration.AppSettings["foobar"]))
throw new SomeStandardException("Application not configured correctly, bozo.");
问题是,我不完全确定SomeStandardException
应该是哪个例外。
我仔细阅读了3.5框架,发现了两个可能的候选人:ConfigurationException
和ConfigurationErrorsException
。
System.Configuration.ConfigurationException
发生配置系统错误时引发的异常。
Remarks
TheConfigurationException
exception is thrown if the application attempts to read or write data to the configuration file but is unsuccessful. Some possible reasons for this can include malformed XML in the configuration file, file permission issues, and configuration properties with values that are not valid.注意:
维护
ConfigurationException
对象是为了向后兼容。ConfigurationErrorsException
对象替换配置系统。
这个例外实际上听起来非常适合我所需要的,但它已被标记为过时,所以,ixnay on atthay。
这给我们带来了令人费解的ConfigurationErrorsException
:
System.Configuration.ConfigurationErrorsException
当前值不是EnableSessionState值之一。
如您所见,其文档完全没用。 (在本地和在线帮助中都是如此。)对课程本身的检查表明,对于我想要的东西来说,这是一种极端的过度杀伤力。
简而言之,我需要一个标准异常,当应用程序配置设置丢失或包含无效值时应抛出该异常。你认为框架有一个例外,它允许应用程序使用它。 (显然它确实如此,但它已被标记为过时,并被更大范围的东西取代。)
你们有什么解决方案,如果有的话,我们将不得不将其吸收并为此推出自己的例外情况?
有些人问我是否可以提供默认值,然后继续。在某些情况下,是的,在这些情况下,不会抛出异常。但是,对于某些设置,这将不适用。例如:数据库服务器名称和凭据,身份验证服务器以及安装的第三方应用程序的路径。
还值得注意的是,我主要处理的应用程序是以批处理模式运行的控制台应用程序,我希望它抛出一个由main方法捕获的异常,如果没有正确配置,则会正确记录。 (这是我继承的遗留代码,目前只是假设一切都很好。)
您不会将异常抛向框架中的现有异常。如果您决定使用现有的例外,则不必完全按照文档中的说明进行操作。该文档将描述框架如何使用给定的异常,但并不意味着对您选择使用/重用现有异常的方式有任何限制。
它是您的应用程序 - 只要您记录它并清楚地指出在缺少配置值的特定情况下将抛出的异常,您可以使用您喜欢的任何异常。如果您确实想要一个非常具体的缺失值指示,您可以考虑编写自己的ConfigurationSettingMissing异常:
[Serializable]
public class ConfigurationMissingException : ConfigurationErrorsException
{}
编辑:在这种情况下编写自己的异常带来额外的好处,保证永远不会有任何关于异常来自框架或您的应用程序的混淆。该框架永远不会抛出您的自定义异常。
更新:我同意这些注释,因此我已将子类更改为Exception中的ConfigurationErrorsException。我认为在可能的情况下从现有的Framework异常中继承自定义异常通常是一个好主意,避免使用Exception类,除非您需要特定于应用程序的异常。
我倾向于不同意你的问题的前提:
简而言之,我需要一个标准异常,当应用程序配置设置丢失或包含无效值时应抛出该异常。你认为框架有一个例外,它允许应用程序使用它。 (显然它确实如此,但它已被标记为过时,并被更大范围的东西取代。)
根据关于System.Exception的MSDN文档(Exception Class,出于性能原因(在Stack Overflow和其他地方的其他人已经指出),你真的不应该抛出用户输入错误的异常。这似乎也有意义 - 如果用户输入输入不正确,为什么你的函数不能返回false,然后让应用程序正常退出?这似乎更像是一个设计问题,然后抛出异常的问题。
正如其他人所指出的那样,如果你真的不得不抛出异常 - 无论出于何种原因 - 没有任何理由你不能通过继承System.Exception来定义你的Exception类型。
您可以尝试继承XML Exception,或者只使用它。
就个人而言,我会使用InvalidOperationException,因为它是对象状态的问题 - 而不是配置系统。毕竟,你不应该允许这些设置由代码设置而不是配置吗?这里的重要部分并不是app.config中没有行,而是没有必要的信息。
对我来说,ConfigurationException(以及它的替代,ConfigurationErrorsException - 尽管有误导性的MSDN文档)是出于配置的保存,读取等错误。
正如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
)
);
}
ConfigurationErrorsException
是抛出你描述的情况的正确例外。 ConfigurationErrorsException
的早期版本的MSDN文档更有意义。
早期的MSDN摘要和备注是:
ConfigurationErrorsException
异常。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)); }
我会把它搞砸并自己滚动......但在你这样做之前,是否有可能让系统假定这个配置设置的默认值?我通常会尝试为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
}
您可以用于配置文件的另一种方法是使用自定义配置节而不是AppSettings
。这样您就可以指定属性IsRequired
和配置系统将为您处理此检查。如果该属性丢失,它将抛出一个ConfigurationErrorsException
,所以我想这支持你应该在你的情况下使用该异常的答案。
我的一般规则是: