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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/417187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:56:01  来源:igfitidea点击:

.NET: Which Exception to Throw When a Required Configuration Setting is Missing?

.netexceptionconfiguration

提问by Mike Hofer

Here's a standard scenario:

这是一个标准场景:

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

The problem is, I am not entirely certain whichexception SomeStandardExceptionshould be.

问题是,我不完全确定应该是哪个例外SomeStandardException

I perused the 3.5 Framework and found two likely candidates: ConfigurationExceptionand ConfigurationErrorsException.

我仔细阅读了 3.5 框架并找到了两个可能的候选者:ConfigurationExceptionConfigurationErrorsException.

System.Configuration.ConfigurationException

The exception that is thrown when a configuration system error has occurred.

Remarks

The ConfigurationExceptionexception 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.

Note:

The ConfigurationExceptionobject is maintained for backward compatibility. The ConfigurationErrorsExceptionobject replaces it for the configuration system.

This exception actually sounds perfect for what I need, but it's been marked obsolete, so, ixnay on atthay.

这个例外实际上听起来很适合我的需要,但它已被标记为过时,因此,在 atthay 上使用 ixnay。

This brings us to the thoroughly puzzling ConfigurationErrorsException:

这给我们带来了彻底令人费解的问题ConfigurationErrorsException

System.Configuration.ConfigurationErrorsException

The current value is not one of the EnableSessionState values.

System.Configuration.ConfigurationErrorsException

当前值不是 EnableSessionState 值之一。

As you can see, its documentation is completely useless. (It's that way in both local and online help.) An examination of the class itself shows that it's drastic overkill for what I want.

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

In a nutshell, I need a standard exception that should be thrown when an application configuration setting is missing or contains an invalid value. You'd think the Framework had such an exception baked into it for applications to use. (It apparently did, but it was marked obsolete, and was replaced by something muchlarger in scope.)

简而言之,我需要一个标准异常,当应用程序配置设置丢失或包含无效值时应该抛出该异常。您可能会认为该框架包含了这样一个例外,供应用程序使用。(它显然没有,但它被标记为已过时,并且被替换的东西范围较大。)

What solutions, if any, are you guys using for this, and am I going to have to suck it up and roll my own exception for this?

什么解决方案,如果有的话,你们正在使用什么解决方案,我是否必须接受它并为此推出我自己的例外?

Edit Addenda

编辑附录

Some have asked whether or not I could provide a default value, and continue. In certain cases, yes, and in those cases, the exception would not be thrown. However, for certain settings, this won't apply. For instance: database server names and credentials, authentication servers, and paths to installed third party applications.

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

It is also worth noting that the application I'm primarily working on is a console application running in batch mode, and I want it to throw an exception that is caught by the main method and logged appropriately if the thing isn't appropriately configured. (It's legacy code I've inherited, and currently just assumeseverything's peachy.)

还值得注意的是,我主要工作的应用程序是一个以批处理模式运行的控制台应用程序,我希望它抛出一个异常,该异常被 main 方法捕获并在未正确配置的情况下正确记录。(这是我继承的遗留代码,目前只是假设一切都很顺利。)

采纳答案by Dave Swersky

You're not limited in your exception-throwing to existing exceptions in the Framework. If you do decide to use existing exceptions, you don't absolutely have to follow the documentation to the letter. The documentation will describe how the frameworkuses a given exception, but doesn't imply any limitation on how youchoose to use/reuse an existing exception.

您的异常抛出不受框架中现有异常的限制。如果您决定使用现有的例外,您不必绝对遵循文档。该文档将描述框架如何使用给定的异常,但并不意味着对选择使用/重用现有异常的方式有任何限制。

It's your application- as long as you document it and clearly indicate the exception that will be thrown in the specific case of a missing configuration value, you can use any exception you like. If you do want a very specific indication of a missingvalue, you might consider writing your own ConfigurationSettingMissing exception:

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

[Serializable]
public class ConfigurationMissingException : ConfigurationErrorsException
{}

EDIT: Writing your own exception in this case carries the added benefit of guaranteeing that there will never be any confusion regarding where the exception is coming from- the framework, or your application. The framework will never throw your custom exceptions.

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

UPDATE: I agree with the comments, so I have changed the subclass to ConfigurationErrorsException from Exception. I think it's generally a good idea to subclass custom exceptions from existing Framework exceptions where possible, avoiding the Exception class unless you need an application-specific exception.

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

回答by Mark Brackett

Personally, I'd use InvalidOperationException, as it's a problem with the object state - not the configuration system. After all, shouldn't you allow these settings to be set by code and not config as well? The important part here is not that there was no line in app.config, but that a required piece of info was not present.

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

To me, ConfigurationException (and it's replacement, ConfigurationErrorsException - despite the misleading MSDN docs) are for errors in saving, reading, etc. of Configuration.

对我来说,ConfigurationException(以及它的替代品 ConfigurationErrorsException - 尽管 MSDN 文档具有误导性)是用于保存、读取配置等方面的错误。

回答by Joe

As Daniel Richardson said, ConfigurationErrorsExceptionis the one to use. In general it is only recommended to create your own custom Exception types if you have a scenario to handle them. In the case of configuration errors, which are usually fatal, this is rarely the case so it's usually more appropriate to reuse the existing ConfigurationErrorsException type.

正如丹尼尔理查森所说,ConfigurationErrorsException是可以使用的。一般来说,如果您有处理它们的场景,则只建议创建您自己的自定义异常类型。对于通常是致命的配置错误,这种情况很少发生,因此通常更适合重用现有的 ConfigurationErrorsException 类型。

Prior to .NET 2.0, the recommendation was to use System.Configuration.ConfigurationException. ConfigurationException became obsolete in .NET 2.0, for reasons which were never clear to me, and the recommendation changed to use ConfigurationErrorsException.

在 .NET 2.0 之前,建议使用System.Configuration.ConfigurationException。ConfigurationException 在 .NET 2.0 中已过时,原因我一直不清楚,建议改为使用 ConfigurationErrorsException。

I use a helper method to throw the exception so that it's easy to change the exception being thrown in one place when migrating from .NET 1.x to 2.0, or if Microsoft decides to change the recommendation again:

我使用辅助方法抛出异常,以便在从 .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
        )
        );
}

回答by Daniel Richardson

ConfigurationErrorsExceptionis the correct exception to throw in the situation you describe. An earlier version of the MSDN documentation for ConfigurationErrorsExceptionmakes more sense.

ConfigurationErrorsException是在您描述的情况下抛出的正确异常。较早版本的 MSDN 文档ConfigurationErrorsException更有意义。

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

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

The earlier MSDN summary and remarks are:

较早的 MSDN 总结和备注是:

  • The exception that is thrown when a configuration-system error has occurred.
  • The ConfigurationErrorsExceptionexception is thrown when any error occurs while configuration information is being read or written.
  • 发生配置系统错误时抛出的异常。
  • ConfigurationErrorsException当在配置信息正被读出或写入发生任何错误则抛出异常。

回答by Gaspar Nagy

The ConfigurationElement class (which is the base class of many config-related classes, like ConfigurationSection) has a method called OnRequiredPropertyNotFound (there are other helper methods too). You can maybe call those.

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

The OnRequiredPropertyNotFound is implemented like this:

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

回答by Charles Bretana

I'd suck it up and roll my own... but before you do that, Is it possible to have the system assume a default value for this configuration setting? I generally attempt to do that for every setting that might get missed bu Ops Management folk... (or perhaps I should say, for as many settings as possible - for some it is clearly not appropriate to have the system make a default decision...)

我会吸收它并自己滚动......但在你这样做之前,是否有可能让系统假设这个配置设置的默认值?我通常会尝试为每个可能被 Ops Management 人员遗漏的设置都这样做......(或者我应该说,对于尽可能多的设置 - 对于某些设置,让系统做出默认决定显然是不合适的。 ..)

in general a custom exception is not a lot of effort... here's an example...

一般来说,自定义异常不需要太多努力......这是一个例子......

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

回答by Yogh

An alternative method you could use for your config files would be to use custom configuration sections as opposed to AppSettings. That way you can specify that a property IsRequiredand the configuration system will handle this checking for you. If the property is missing it will throw a ConfigurationErrorsExceptionso I suppose that supports the answer that you should use that exception in your case.

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

回答by Hershi

My general rule would be:

我的一般规则是:

  1. If the case of the missing configuration is not very common and I believe I would never want to handle this case differently than other exceptions, I just use the basic "Exception" class with an appropriate message:

    throw new Exception("my message here")

  2. If I do want, or think there's a high probability I would want to handle this case in a different manner than most other exceptions, I would roll my own type as people have already suggested here.

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

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

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

回答by Matt Jordan

I tend to disagree with the premise of your question:

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

In a nutshell, I need a standard exception that should be thrown when an application configuration setting is missing or contains an invalid value. You'd think the Framework had such an exception baked into it for applications to use. (It apparently did, but it was marked obsolete, and was replaced by something much larger in scope.)

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

According to the MSDN documentation on System.Exception (Exception Class, you really shouldn't be throwing exceptions for user input errors, for performance reasons (which has been pointed out by others on Stack Overflow and elsewhere). This seems to make sense as well - why can't your function return false if the user input is entered incorrectly, and then have the application gracefully exit? This seems to be more of a design problem then an issue with which Exception to throw.

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

As others have pointed out, if you really haveto thrown an exception - for whatever reason - there isn't any reason why you couldn't define your Exception type by inheriting from System.Exception.

正如其他人指出的那样,如果您真的必须抛出异常 - 无论出于何种原因 - 没有任何理由不能通过继承 System.Exception 来定义您的异常类型。