.NET: Какое исключение выдается, когда требуемый параметр конфигурации отсутствует? - PullRequest
112 голосов
/ 06 января 2009

Вот стандартный сценарий:

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

Проблема в том, что я не совсем уверен, , какое исключение SomeStandardException должно быть.

Я изучил 3.5 Framework и нашел двух вероятных кандидатов: ConfigurationException и ConfigurationErrorsException.

System.Configuration.ConfigurationException

Исключение, которое выдается, когда ошибка конфигурации системы произошло.

Замечания

ConfigurationException Исключение составляет бросить, если приложение пытается читать или записывать данные в файл конфигурации, но есть безуспешными. Некоторые возможные причины для этого может включать в себя искаженный XML в файл конфигурации, файл вопросы разрешения и конфигурации свойства со значениями, которые не являются действительный.

Примечание:

Объект ConfigurationException поддерживается для обратной совместимости. ConfigurationErrorsException объект заменяет его для Конфигурация системы.

Это исключение на самом деле звучит идеально для того, что мне нужно, но оно помечено как устаревшее, так что ixnay на atthay.

Это подводит нас к совершенно загадочным ConfigurationErrorsException:

System.Configuration.ConfigurationErrorsException

Текущее значение не является одним из Значения EnableSessionState.

Как видите, его документация совершенно бесполезна. (Это относится как к локальной, так и к интерактивной справке.) Проверка самого класса показывает, что это радикальное излишество для того, что я хочу.

Короче говоря, мне нужно стандартное исключение, которое должно создаваться, если параметр конфигурации приложения отсутствует или содержит недопустимое значение. Вы могли бы подумать, что в платформе есть такое исключение, запрограммированное для приложений (По-видимому, так и было, но оно было помечено как устаревшее и было заменено чем-то намного большего по объему.)

Какие решения, если таковые имеются, вы, ребята, используете для этого, и мне придется смириться с этим и выдвинуть свое собственное исключение для этого?

Редактировать приложения

Некоторые спрашивают, могу ли я предоставить значение по умолчанию и продолжаю. В некоторых случаях да, и в этих случаях исключение не будет выброшено. Однако для определенных настроек это не будет применяться. Например: имена и учетные данные сервера базы данных, серверы аутентификации и пути к установленным сторонним приложениям.

Стоит также отметить, что приложение, над которым я в основном работаю, является консольным приложением, работающим в пакетном режиме, и я хочу, чтобы оно генерировало исключение, которое перехватывается основным методом и соответствующим образом регистрируется, если это не так. соответствующим образом настроен. (Это устаревший код, который я унаследовал, и в настоящее время только предполагает все хорошо.)

Ответы [ 11 ]

41 голосов
/ 06 января 2009

Лично я бы использовал InvalidOperationException , так как это проблема с состоянием объекта, а не с системой конфигурации. В конце концов, разве вы не должны позволять устанавливать эти параметры по коду, а не по настройке? Важной частью здесь является не то, что в app.config не было строки, а то, что требуемая часть информации отсутствовала.

Для меня ConfigurationException (и его замена, ConfigurationErrorsException - несмотря на вводящие в заблуждение документы MSDN) предназначены для ошибок при сохранении, чтении и т. Д. Конфигурации.

31 голосов
/ 06 января 2009

Вы не ограничены в выдаче исключений существующими исключениями в Framework. Если вы решите использовать существующие исключения, вам не обязательно следовать документации к письму. В документации будет описано, как framework использует данное исключение, но не налагает никаких ограничений на то, как you решит использовать / повторно использовать существующее исключение.

Это ваше приложение - пока вы его документируете и четко указываете исключение, которое будет выдано в конкретном случае пропущенного значения конфигурации, вы можете использовать любое понравившееся исключение. Если вы хотите получить очень конкретное указание на отсутствующее значение, вы можете написать собственное исключение ConfigurationSettingMissing:

[Serializable]
public class ConfigurationMissingException : ConfigurationErrorsException
{}

РЕДАКТИРОВАТЬ: написание собственного исключения в этом случае дает дополнительное преимущество, гарантирующее, что никогда не возникнет путаницы в отношении того, откуда исходит исключение - платформа или ваше приложение. Фреймворк никогда не будет выдавать ваши пользовательские исключения.

ОБНОВЛЕНИЕ: Я согласен с комментариями, поэтому я изменил подкласс на ConfigurationErrorsException с Exception. Я думаю, что, как правило, рекомендуется создавать подклассы пользовательских исключений из существующих исключений Framework по возможности, избегая класса Exception, если только вам не требуется исключение для конкретного приложения.

17 голосов
/ 06 января 2009

Как сказал Даниэль Ричардсон, 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
        )
        );
}
15 голосов
/ 05 мая 2009
8 голосов
/ 06 января 2009

ConfigurationErrorsException - правильное исключение для ситуации, которую вы описываете. Более ранняя версия документации MSDN для ConfigurationErrorsException имеет больше смысла.

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

Более ранняя сводка и примечания MSDN:

  • Исключение, которое выдается, когда ошибка конфигурации системы произошло.
  • ConfigurationErrorsException исключение выдается при любой ошибке происходит во время конфигурации информация читается или написано.
6 голосов
/ 06 января 2009

Класс 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)); }
1 голос
/ 08 июля 2011

Альтернативный метод, который вы могли бы использовать для своих файлов конфигурации, - использовать пользовательские разделы конфигурации, а не AppSettings. Таким образом, вы можете указать, что свойство IsRequired и система конфигурации будут обрабатывать эту проверку для вас. Если свойство отсутствует, оно выдаст ConfigurationErrorsException, поэтому я предполагаю, что это поддерживает ответ, что вы должны использовать это исключение в вашем случае.

1 голос
/ 06 января 2009

Я бы смирился с этим и свернул свой собственный ... но прежде чем вы это сделаете, возможно ли, чтобы система приняла значение по умолчанию для этого параметра конфигурации? Как правило, я пытаюсь сделать это для каждого параметра, который может быть пропущен, но люди Ops Management ... (или, может быть, я должен сказать, для максимально возможного количества параметров - для некоторых явно неуместно, чтобы система принимала решение по умолчанию. ..)

в общем случае пользовательское исключение не требует больших усилий ... вот пример ...

[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
}
0 голосов
/ 06 января 2009

Я склонен не согласиться с предпосылкой вашего вопроса:

Короче говоря, мне нужно стандартное исключение, которое должно создаваться, если параметр конфигурации приложения отсутствует или содержит недопустимое значение. Вы могли бы подумать, что в платформе есть такое исключение, запрограммированное для приложений (По-видимому, так и было, но оно было помечено как устаревшее и было заменено чем-то гораздо большим по объему.)

В соответствии с документацией MSDN System.Exception ( Класс исключений ) вам действительно не следует выбрасывать исключения из-за ошибок пользовательского ввода по соображениям производительности (на что другие указывали при переполнении стека и в другом месте). Это также имеет смысл - почему ваша функция не может возвращать false, если пользовательский ввод введен неправильно, а затем приложение корректно завершает работу? Это скорее проблема проектирования, чем проблема, с которой возникла исключительная ситуация. бросить.

Как уже отмечали другие, если у вас действительно есть для выдачи исключения - по какой-либо причине - нет никаких причин, по которым вы не могли бы определить свой тип исключения, наследуя его от System.Exception.

0 голосов
/ 06 января 2009

Моё общее правило:

  1. Если случай с отсутствующей конфигурацией встречается не очень часто, и я считаю, что никогда не захочу обрабатывать этот случай иначе, чем другие исключения, я просто использую базовый класс «Исключение» с соответствующим сообщением:

    выбрасывать новое исключение («мое сообщение здесь»)

  2. Если я действительно хочу или думаю, что есть большая вероятность, что я захочу обработать этот случай иначе, чем большинство других исключений, я бы выбрал свой собственный тип, как люди уже предложили здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...